Search code examples
pythonstringsocketssend

Python sending mutliple strings using socket.send() / socket.recv()


I am trying to send multiple strings using the socket.send() and socket.recv() function.

I am building a client/server, and "in a perfect world" would like my server to call the socket.send() function a maximum of 3 times (for a certain server command) while having my client call the socket.recv() call 3 times. This doesn't seem to work the client gets hung up waiting for another response.

server:

        clientsocket.send(dir)
        clientsocket.send(dirS)
        clientsocket.send(fileS)

client

response1 = s.recv(1024)
if response1:
    print "\nRecieved response: \n" , response1
response2 = s.recv(1024)
if response2:
    print "\nRecieved response: \n" , response2
response3 = s.recv(1024)
if response3:
    print "\nRecieved response: \n" , response3

I was going through the tedious task of joining all my strings together then reparsing them in the client, and was wondering if there was a more efficient way of doing it?

edit: My output of response1 gives me unusual results. The first time I print response1, it prints all 3 of the responses in 1 string (all mashed together). The second time I call it, it gives me the first string by itself. The following calls to recv are now glitched/bugged and display the 2nd string, then the third string. It then starts to display the other commands but as if it was behind and in a queue.

Very unusual, but I will likely stick to joining the strings together in the server then parsing them in the client


Solution

  • You wouldn't send bytes/strings over a socket like that in a real-world app.

    You would create a messaging protocol on-top of the socket, then you would put your bytes/strings in messages and send messages over the socket.

    You probably wouldn't create the messaging protocol from scratch either. You'd use a library like nanomsg or zeromq.

    server

    from nanomsg import Socket, PAIR
    sock = Socket(PAIR)
    sock.bind('inproc://bob')
    sock.send(dir)
    sock.send(dirS)
    sock.send(fileS)
    

    client

    from nanomsg import Socket, PAIR
    sock = Socket(PAIR)
    sock.bind('inproc://bob')
    response1 = sock.recv()
    response2 = sock.recv()
    response3 = sock.recv()
    

    In nanomsg, recv() will return exactly what was sent by send() so there is a one-to-one mapping between send() and recv(). This is not the case when using lower-level Python sockets where you may need to call recv() multiple times to get everything that was sent with send().