2

I want to send/receive 'portioned' data using TCP Python socket module. My receiving server side socket is set to receive 40 bytes of data in a single recv call:

while True:
    data = connection.recv(40)
    if not data:
        break
    ...
connection.close()

I have some sample data ~500 bytes long, converter to bytes object, that is being sent to 'server' by 'client':

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
...
s.send(sample_data)

Although I only have one call to send method does it mean that client sends 40 bytes of 'sample_data' at a time while server 'requests' 40 bytes at once for as long as whole package is not sent completely?

I found in this post there's SO_SNDBUF parameter that sets size of send buffer for socket, but how is it different from 'ordinary' socket without SO_SNDBUF being set?

buffer_size = 40
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF, buffer_size)
...
s.send(sample_data)
Stan Reduta
  • 3,292
  • 5
  • 31
  • 55

1 Answers1

4

TCP is a streaming protocol, meaning there are no message boundaries. It is just a stream of bytes. Think of it as a FIFO. If client sends 500 bytes, then there will be 500 total bytes to receive on the server. A recv(40) will receive from 1-40 bytes in the order sent. You must check the return value to see how much you received.

You could receive data lengths of: 40,40,40,40,40,40,40,40,40,40,40,40,20

Or you could receive something like: 40,40,5,40,40,40,40,40,40,40,40,40,40,15

Making another recv(40) on a blocking socket will then hang until at least one more byte is received, or return zero bytes if the client closes the socket.

It is up to the server to concatenate the data together and determine whether a complete data transmission was received or not. Normally you'll need to define a protocol to decide what a complete message entails. This could be "500 bytes is a complete message". You'll also need to handle the case that two messages were sent and a single recv could get data from the end of one message and the beginning of another.

You do not normally need to adjust the buffer size with socket options.

Mark Tolonen
  • 166,664
  • 26
  • 169
  • 251
  • Thanks a lot for the explanation! May I ask you to add couple more words on "defining protocol to decide what a complete message is" and also the situation where recv gets data from different parts of two messages? Because that's what I'm trying to achieve and I cannot find proper explanation anywhere. – Stan Reduta Feb 10 '18 at 09:11
  • 1
    @Stan Here's another answer I wrote with some more detail: https://stackoverflow.com/a/9968240/235698 – Mark Tolonen Feb 11 '18 at 21:49