我有一个运行服务器的覆盆子,可以与笔记本电脑上的服务器通信。我通过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))
在客户端代码中设置print语句会产生(x,y,z),这是预期的输出。但是,在服务器上接收数据后,它将以模式显示:
(x,y,z)(x,y,z)
(x,y,z)
(x,y,z)
(x,y,z)(x,y,z)
...
为什么数据是重复的?它是TCP的属性吗?如果是这样,我怎么能反击这个来接收数据作为我最初发送的字符串。
答案 0 :(得分:2)
TCP将数据作为流发送。您可以将数据写入该流,并且可以从该流接收数据。重要的是,虽然可以是一个发送对应于一个接收的情况,但根本不能保证是这种情况。你可以发送一个大块并以一堆较小的块接收它,或者你可以发送一堆较小的块并接收一大块,或者介于两者之间的任何东西。你处于后一种情况。
要解决此问题,您需要在TCP之上层叠某种成帧协议。您可以采用以下两种主要方式:
使用消息的长度为每条消息添加前缀,然后读取那么多字节。
在每封邮件之间加上分隔符。
出于您的目的(发送没有换行符的纯文本),后者用换行符作为分隔符可能没问题。您可以想出如何做到这一点,但实际上,重复这样做:
如果您正在进行打印,则可以通过循环替换所有内容,从套接字接收然后写入stdout
。