Python套接字服务器接收到重复数据

3

我有一个树莓派运行着一个服务器,与我笔记本电脑上的服务器进行通信。我是通过Python的简单套接字连接来实现这一点的。

像这样:

服务器

HOST = "192.168.0.115"
PORT = 5001
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST,PORT))
s.listen(1)

conn, addr = s.accept()
while conn:
    data = conn.recv(1024)
    print data
    if not data:
         break
conn.close()

客户端

__init__(self,addr,port,timeout):
   self.addr = addr
   self.port = port
   self.timeout = timeout
   self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
   self.socket.connect((self.addr,self.port))

#in a different file the call to send is made, passes list object as a parameter

send(self,data):
    if self.socket:
        self.socket.send(str(data))

在客户端代码中设置一个打印语句会输出期望的结果(x,y,z)。但是,在服务器上接收数据时,它呈现出一种模式:
(x,y,z)(x,y,z)
(x,y,z)
(x,y,z)
(x,y,z)(x,y,z)
...

为什么数据会被接收为重复的?这是TCP的属性吗?如果是,我该如何解决这个问题,以便像最初发送的字符串一样只接收一次数据。


从客户端的代码片段很难确定情况,您能否提供目前为止的更多代码? - tijko
添加了额外的客户信息。 - cmcdaniels
发送的消息为 (x,y,z),接收方显示为具有重复的 (x,y,z)。 - cmcdaniels
有点儿与问题无关的东西。通过将客户端/服务器代码隔离到自己的片段中,可以重新创建问题,这让我相信问题存在于实际的传输协议中。 - cmcdaniels
1个回答

3
TCP以流的方式发送数据。您可以向该流写入数据,也可以从该流接收数据。重要的是,虽然一个发送对应一个接收可能是一种情况,但这并不保证一定会出现这种情况。您可以发送一个大块并将其分成许多小块进行接收,或者您可以发送许多小块并接收一个大块,或者介于两者之间。您处于后一种情况。
为了解决这个问题,您需要在TCP之上加入某种分帧协议。有两种主要方法:
1.在每条消息前缀中加入消息的长度,然后读取那么多字节。 2.在每条消息之间放置定界符。
对于您的目的(发送没有换行符的纯文本),后者使用换行符作为定界符可能很好。您可能可以想出如何做到这一点,但基本上,需要反复执行以下操作:
1.接收一些数据。 2.将该数据附加到缓冲区。 3.搜索换行符并处理到该点的缓冲区。重复此步骤直到没有更多换行符为止。
如果您只是打印,您可以通过循环、从套接字接收然后写入stdout来替换所有这些操作。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接