简体   繁体   English

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

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

I'm having some trouble identifying the cause of some packet splitting issues on a Python-based TCP server I am hosting.我在确定我托管的基于 Python 的 TCP 服务器上的某些数据包拆分问题的原因时遇到了一些麻烦。

After my client has connected to the server, it sends a string to the server, followed by /n .我的客户端连接到服务器后,它会向服务器发送一个字符串,后跟/n

A Wireshark preview of a packet can be seen below:可以在下面看到数据包的 Wireshark 预览: 在此处输入图片说明

In this case, you can see the payload is "as the extra special british baby potatoes/n"在这种情况下,您可以看到有效载荷是“作为额外的特殊英国小土豆/n”

My TCP Server has the following receiving code:我的 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

When receiving the above packet, it prints the following:当接收到上述数据包时,它会打印以下内容:

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

Somehow, this single TCP packet has been split into 3 smaller packets.不知何故,这个单一的 TCP 数据包被分成了 3 个更小的数据包。

Do you know how this may have happened?你知道这可能是怎么发生的吗?

TCP is not a message based protocol but a byte stream. TCP 不是基于消息的协议,而是字节流。 A single send does not mean that everything will be sent inside a single TCP packet.单次send并不意味着所有内容都将在单个 TCP 数据包内发送。 Similarly it cannot be counted on that a single recv will match a single send .同样,不能指望单个recv将匹配单个send

If you want message semantics you need to add these on top of the byte stream.如果您想要消息语义,您需要将这些添加到字节流之上。 Typically this is done with an explicit length indicator, a special separator or by having only a single message, ie close of connection will end the message.通常,这是通过显式长度指示符、特殊分隔符或仅具有单个消息来完成的,即连接关闭将结束消息。 And then you need to call recv multiple times until you got the full message.然后你需要多次调用recv直到你得到完整的消息。

In accordance with the explanation of Steffen Ullrich here is how you can structure your code to receive the whole message:根据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