Search code examples
pythonsocketstcprpcmsgpack

RPC over TCP with multiple clients on same machine


I'm building an RPC Server in golang that uses msgpack. The client is built in python using the mprpc library (msgpack over TCP with gevent).

My issue is, being an absolute noob in networking, I discovered that I can't use the same address/port with multiple clients running at once on the same computer (socket already bound i guess, it just stalls and timeouts).

I have looked around quite a bit but I'm not sure what I should be doing to be able to have multiple clients on the same machine talk to a server (msgpack back and forth). Is this a case where I need to use ZeroMQ ? Or requests over HTTP ?

Thanks !


Solution

  • TCP is a connection-oriented protocol. This means that only the server needs to have a fixed, known port. The client can use any port it wants, because nobody is making a connection to the client.

    So, how does the server know how to talk to the client? Whenever it accepts a connection, it's told who the connection is from. But usually, you don't even need that, because the socket keeps track of who the connection is from. Just recv and send on that socket, and you're talking to the right client.


    You should probably read the Socket Programming HOWTO in the Python docs, or some other tutorial, but briefly…

    A server starts like this:

    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    sock.bind(('', 12345))
    sock.listen(5)
    while True:
        csock, addr = sock.accept()
    

    It binds a port and listens and loops around accepting connections and doing something with them.

    A client, on the other hand, just does this:

    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.connect(('localhost', 12345))
    

    … or, equivalently:

    sock = socket.create_connection(('localhost', 12345))
    

    It doesn't call bind, it just creates a connection, letting the sockets library pick an arbitrary port on the appropriate interface for that connection. Unless you've got thousands of sockets already open, it should always be able to find a free port for you.