简体   繁体   中英

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.

After my client has connected to the server, it sends a string to the server, followed by /n .

A Wireshark preview of a packet can be seen below: 在此处输入图片说明

In this case, you can see the payload is "as the extra special british baby potatoes/n"

My TCP Server has the following receiving code:

    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.

Do you know how this may have happened?

TCP is not a message based protocol but a byte stream. A single send does not mean that everything will be sent inside a single TCP packet. Similarly it cannot be counted on that a single recv will match a single 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.

In accordance with the explanation of Steffen Ullrich here is how you can structure your code to receive the whole message:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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