我正在使用TCP与Python套接字,将数据从一台计算机传输到另一台计算机。但是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
一起发送,但是当收到邮件时,当我打印到达邮件的长度时,长度有时是错误的,有时是正确的。< / p>
921600
921600
921923 # wrong
922601 # wrong
921682 # wrong
921600
921600
921780 # wrong
如你所见,错误的到达没有模式。当我使用TCP时,我期望更多的一致性,但是看起来缓冲区被混淆并以某种方式接收下一条消息的一部分,因此产生更长的消息。 这里有什么问题?
我尝试添加代码的相关部分,如果您愿意,我可以添加更多代码,但代码在localhost
上运行良好但在两台计算机上运行失败,因此除了传输部分之外应该没有错误
编辑1:我稍微检查过这个question,它提到客户端中的所有发送命令都可能无法通过服务器中的单个recv接收,但我无法理解将其应用于练习。
答案 0 :(得分:1)
TCP是一种流协议。您发送的数据块的大小与您收到的数据块之间绝对没有连接。如果您想要接收已知大小的数据,那么完全由您决定只请求那么多数据:您当前每次都要请求数据的总长度,这将尝试阅读太多,除非在第一次.recv()
调用中检测到整个数据的情况不太可能发生。基本上,您需要执行data = conn.recv(message_size - len(image_string))
之类的操作来反映剩余数据量正在减少的事实。
答案 1 :(得分:1)
将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
仅返回请求的字节数,并在缓冲区中留下任何额外的内容。