为什么循环Python TCP接收器部分接收消息?

为什么循环Python TCP接收器部分接收消息?,python,tcp,Python,Tcp,我有一个服务器,可以向客户端发送一些消息。print(trades)语句显示文件读取器正确读取整个csv: def send_past_trades(self): with open('OTC_trade_records.csv',newline='') as f: connectionSocket, addr = self.client trades = f.read() #print(trades

我有一个服务器,可以向客户端发送一些消息。print(trades)语句显示文件读取器正确读取整个csv:

    def send_past_trades(self):
        with open('OTC_trade_records.csv',newline='') as f:
            connectionSocket, addr = self.client
            trades = f.read()
            #print(trades)
            connectionSocket.send(trades.encode())
我的客户接收者是这样的:

msg = b""
while(True):
    print("Batch receiving")
    tmp = client_socket.recv(4096)
    msg += tmp
    if len(tmp) < 4096:
        print(len(tmp))
        break
msg = msg.decode()
print(msg)
msg=b“”
虽然(正确):
打印(“批量接收”)
tmp=客户机_socket.recv(4096)
味精+=tmp
如果len(tmp)<4096:
打印(len(tmp))
打破
msg=msg.decode()
打印(msg)
信息总是不完整的。我可以看到,“批接收”语句只打印一次,当break语句启动时,最后一条消息的长度是1228

另一点是,该代码在我的本地系统中运行良好。当我把服务器程序放到远程服务器机器上时,问题就出现了。服务器是否有可能干预该消息

注意:我尝试了不同的方法来解决这个问题,比如在一个循环中只发送1024b个包大小的消息。仍收到部分消息。

问题在于:

如果len(tmp)<4096:
打印(len(tmp))
打破
关键是
recv(bufsize)
中的
bufsize
是接收的最大大小。如果可用字节数较少,
recv
将返回较少的字节

我建议定义一个简单的通信协议,用头和负载描述消息的结构。收割台必须包含有效负载大小。这允许您解析来自传入TCP流的数据,并获得接收数据的确切大小。然后您可以接收请求的数据量

客户端将如下所示:

msg = b""
while(True):
    print("Batch receiving")
    tmp = client_socket.recv(4096)
    msg += tmp
    if len(tmp) < 4096:
        print(len(tmp))
        break
msg = msg.decode()
print(msg)
导入结构
#接收标题
标题=连接.recv(8)
(长度,)=struct.unpack('>Q',header)#解析有效负载长度
#接收有效载荷
有效载荷=b“
而len(有效载荷)<长度:
to_read=长度-长度(有效载荷)
有效负载+=connection.recv(4096如果to_read>4096,否则to_read)
服务器:

导入结构
将open('OTC_trade_records.csv',换行='')作为f:
connectionSocket,addr=self.client
交易=f.读取()
长度=结构包('>Q',长度(交易))
connectionSocket.sendall(长度)
连接Socket.sendall(交易)
问题在于:

如果len(tmp)<4096:
打印(len(tmp))
打破
关键是
recv(bufsize)
中的
bufsize
是接收的最大大小。如果可用字节数较少,
recv
将返回较少的字节

我建议定义一个简单的通信协议,用头和负载描述消息的结构。收割台必须包含有效负载大小。这允许您解析来自传入TCP流的数据,并获得接收数据的确切大小。然后您可以接收请求的数据量

客户端将如下所示:

msg = b""
while(True):
    print("Batch receiving")
    tmp = client_socket.recv(4096)
    msg += tmp
    if len(tmp) < 4096:
        print(len(tmp))
        break
msg = msg.decode()
print(msg)
导入结构
#接收标题
标题=连接.recv(8)
(长度,)=struct.unpack('>Q',header)#解析有效负载长度
#接收有效载荷
有效载荷=b“
而len(有效载荷)<长度:
to_read=长度-长度(有效载荷)
有效负载+=connection.recv(4096如果to_read>4096,否则to_read)
服务器:

导入结构
将open('OTC_trade_records.csv',换行='')作为f:
connectionSocket,addr=self.client
交易=f.读取()
长度=结构包('>Q',长度(交易))
connectionSocket.sendall(长度)
连接Socket.sendall(交易)

循环运行一次,第二次运行时,在我更改代码后,在tmp=client_socket.recv(4096)处卡住。啊,是的,你说得对。如果不关闭服务器端的连接,可能会发生死锁。我改正了我的答案。我的错。我以前在别的地方设置了settimeout。你的建议行得通。谢谢,为什么会出现僵局?它是来自服务器端运行的多线程吗?如果是这样的话,struct和sendall是如何解决这个问题的呢。这是阻止TCP接收的正常行为。客户端正在等待连接的套接字上的任何数据。循环运行一次,在第二次运行中,在我更改代码后,在tmp=Client_socket.recv(4096)处卡住。啊,是的,你是对的。如果不关闭服务器端的连接,可能会发生死锁。我改正了我的答案。我的错。我以前在别的地方设置了settimeout。你的建议行得通。谢谢,为什么会出现僵局?它是来自服务器端运行的多线程吗?如果是这样的话,struct和sendall是如何解决这个问题的呢。这是阻止TCP接收的正常行为。客户端正在等待连接的套接字上的任何数据。