我在Python套接字中使用TCP,将数据从一台计算机传输到另一台计算机。但是,recv
命令读取的内容比服务器端应该读取的要多,因此我找不到问题。
client.py
while rval:
image_string = frame.tostring()
sock.sendall(image_string)
rval, frame = vc.read()
server.py
while True:
image_string = ""
while len(image_string) < message_size:
data = conn.recv(message_size)
image_string += data
消息的长度是921600 (message_size)
,所以它是用sendall
发送的,但是当收到消息时,当我打印到达消息的长度时,长度有时是错误的,有时是正确的。
921600
921600
921923 # wrong
922601 # wrong
921682 # wrong
921600
921600
921780 # wrong
正如你所看到的,错误的到达没有模式。当我使用TCP时,我希望有更多的一致性,但是似乎缓冲区混淆了,并以某种方式接收了下一条消息的一部分,因此产生了一条更长的消息。这里有什么问题?
我试着只添加代码的相关部分,如果您愿意,我可以添加更多代码,但是代码在localhost
上表现良好,但在两台计算机上失败,因此除了发送部分之外,不存在错误。
Edit1: --我稍微检查了一下这个question,它提到客户机中的所有发送命令都可能不会被服务器中的一个recv接收,但是我不知道如何将其应用到实践中。
发布于 2017-10-23 09:46:07
TCP是一种流协议。您发送的数据块的大小与您接收的数据块之间绝对没有任何联系。如果您想要接收已知大小的数据,则完全取决于您是否只请求那么多数据:当前每次都请求数据的总长度,这将尝试读取太多数据,除非在第一个.recv()
调用检索到整个数据的不太可能的情况下。基本上,您需要做一些类似data = conn.recv(message_size - len(image_string))
的事情,以反映剩余数据量正在减少的事实。
发布于 2017-10-23 10:52:09
将TCP看作是字节的原始流。跟踪你在流中的位置并正确地解释它是你的责任。缓冲所读取的内容,并仅提取当前需要的内容。
下面是一个(未经测试的)类来说明:
class Buffer:
def __init__(self,socket):
self.socket = socket
self.buffer = b''
def recv_exactly(self,count):
# Could return less if socket closes early...
while len(self.buffer) < count:
data = self.socket.recv(4096)
if not data: break
self.buffer += data
ret,self.buffer = self.buffer[:count],self.buffer[count:]
return ret
recv
总是请求相同数量的数据,并在缓冲区中对其进行排队。recv_exactly
只返回请求的字节数,并在缓冲区中保留任何额外的字节数。
https://stackoverflow.com/questions/46894768
复制相似问题