繁体   English   中英

Python TCP Server 接收拆分为多个数据包的单个 TCP 数据包

[英]Python TCP Server receives single TCP packet split into multiple packets

我在确定我托管的基于 Python 的 TCP 服务器上的某些数据包拆分问题的原因时遇到了一些麻烦。

我的客户端连接到服务器后,它会向服务器发送一个字符串,后跟/n

可以在下面看到数据包的 Wireshark 预览: 在此处输入图片说明

在这种情况下,您可以看到有效载荷是“作为额外的特殊英国小土豆/n”

我的 TCP 服务器有以下接收代码:

    def listenToClient(self, client, address):
        size = 1024
        while True:
            try:
                # Receive data from the client
                data = client.recv(size)
                print('CLIENT Data Received', client)
                print(datetime.now())
                print("Raw data received: ", data.hex())
                Data: as the extra
            except ConnectionAbortedError:
                print(datetime.now())
                print('CLIENT Disconnected:', client)
                client.close()
                return False

当接收到上述数据包时,它会打印以下内容:

CLIENT Data Received <socket.socket fd=428, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('192.168.0.16', 12345), raddr=('192.168.0.14', 47234)>
2020-11-14 22:48:20.087507
Raw data received:  617320746865206578747261
Data: as the extra

CLIENT Data Received <socket.socket fd=428, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('192.168.0.16', 12345), raddr=('192.168.0.14', 47234)>
2020-11-14 22:48:20.092495
Raw data received:  207370656369616c2062726974697368206261627920706f7461
Data:  special british baby pota

CLIENT Data Received <socket.socket fd=428, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('192.168.0.16', 12345), raddr=('192.168.0.14', 47234)>
Raw data received:  746f65730a0a
2020-11-14 22:48:20.117488
Data: toes

不知何故,这个单一的 TCP 数据包被分成了 3 个更小的数据包。

你知道这可能是怎么发生的吗?

TCP 不是基于消息的协议,而是字节流。 单次send并不意味着所有内容都将在单个 TCP 数据包内发送。 同样,不能指望单个recv将匹配单个send

如果您想要消息语义,您需要将这些添加到字节流之上。 通常,这是通过显式长度指示符、特殊分隔符或仅具有单个消息来完成的,即连接关闭将结束消息。 然后你需要多次调用recv直到你得到完整的消息。

根据Steffen Ullrich的解释,这里是如何构建代码以接收整个消息:

def listenToClient(self, client, address):
        size = 1024
        while True:
            try:
                # Receive data from the client
                data = ''
                while True:
                     r = client.recv(size)
                     if not r:
                         break
                     data += r
                print('CLIENT Data Received', client)
                print(datetime.now())
                print("Raw data received: ", data.hex())
                Data: as the extra
            except ConnectionAbortedError:
                print(datetime.now())
                print('CLIENT Disconnected:', client)
                client.close()
                return False

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM