I have a server that’s written in C, and I want to write a client in python. The python client will send a string ‘send some_file’ when it wants to send a file, followed by the file’s contents, and the string ‘end some_file’. Here is my client code :
file = sys.argv[1] host = sys.argv[2] port = int(sys.argv[3]) sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM) sock.connect((host,port)) send_str = 'send %s' % file end_str = 'end %s' % file sock.send(send_str) sock.send('\n') sock.send(open(file).read()) sock.send('\n') sock.send(end_str) sock.send('\n')
The problem is this :
-
the server receives the ‘send some_file’ string from a recv
-
at the second recv, the file’s content and the ‘end file’ strings are sent together
In the server code, the buffer’s size is 4096. I first noticed this bug when trying to send a file that’s less than 4096k. How can I make sure that the server receives the strings independently?
With socket programming, even if you do 2 independent sends, it doesn’t mean that the other side will receive them as 2 independent recvs.
One simple solution that works for both strings and binary data is to: First send the number of bytes in the message, then send the message.
Here is what you should do for each message whether it is a file or a string:
Sender side:
Receiver side:
Along with the 4-byte length header I mentioned above, you could also add a constant size command type header (integer again) that describes what’s in the following recv.
You could also consider using a protocol like HTTP which already does a lot of the work for you and has nice wrapper libraries.