May
23
Sockets are byte streams, not message streams
The first time you try to write a network client or server directly on top of sockets, you do something like this:
for filename in filenames: with open(filename, 'rb') as f: sock.sendall(f.read())
And then, on the other side:
for i in count(0): msg = sock.recv(1<<32) if not msg: break with open('file{}'.format(i), 'wb') as f: f.write(msg)
At first, this seems to work, but it fails on larger files. Or as soon as you try to use it across the internet. Or 1% of the time. Or when the computer is busy.
In reality, it can't possibly work, except in special circumstances. A TCP socket is a stream of bytes. Every time you call send (or sendall), you put more bytes on that stream. Every time you call recv, you get some or all of the bytes on the stream.
for filename in filenames: with open(filename, 'rb') as f: sock.sendall(f.read())
And then, on the other side:
for i in count(0): msg = sock.recv(1<<32) if not msg: break with open('file{}'.format(i), 'wb') as f: f.write(msg)
At first, this seems to work, but it fails on larger files. Or as soon as you try to use it across the internet. Or 1% of the time. Or when the computer is busy.
In reality, it can't possibly work, except in special circumstances. A TCP socket is a stream of bytes. Every time you call send (or sendall), you put more bytes on that stream. Every time you call recv, you get some or all of the bytes on the stream.