0

I am working on a client-server architecture in which several clients shall transfer files to a running server. I am wondering whether it is possible for the server to receive input on one port from different clients at the same time.

My code so far:

Server

import socket
import time

mySocket = socket.socket( socket.AF_INET, socket.SOCK_STREAM )

# EDIT: This line was added based on @Aleksander Gurin's response below. The problem persists.
mySocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

mySocket.bind( ('localhost', 1234 ) )


mySocket.listen( 2 )

channel, details = mySocket.accept()

while True:

    incoming = channel.recv( 100 )

    if incoming: 
        print "Received >%s<" % incoming
        incoming = ''

Client

import sys
import socket
import time

mySocket = socket.socket( socket.AF_INET, socket.SOCK_STREAM ) 

mySocket.connect( ('127.0.0.1', 1234) )

counter = 1

while True:
    mySocket.send( "Message %03d from client %s." % (counter, sys.argv[1]) )
    time.sleep(2)
    counter += 1

I am starting two instances of the client like so:

./client.py 1 &
./client.py 2 &

So far, however, my server is only receiving input from one client:

Received >Message 001 from client 1.<
Received >Message 002 from client 1.<
Received >Message 003 from client 1.<
Received >Message 004 from client 1.<
Received >Message 005 from client 1.<
...

My question therefore is: Is it possible to receive the postings from the second client on the server as well - and if so, how?

P. S.: I checked this related SO post but could not really extract an answer from that either.

Community
  • 1
  • 1
Pat
  • 353
  • 1
  • 4
  • 15

1 Answers1

1

You need to set SO_REUSEADDR socket option before you bind the socket. This is so-called socket-level option. The result server would lock something like this:

import socket, threading

def handler(s):
    data = "none"
    while len(data):
        data = s.recv(4096)
        print "Data: %s"%(data)
    s.close()

if __name__ == "__main__":
    tcpsocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    # here you set socket options, this is what you need
    tcpsocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    # than you bind the socket
    tcpsocket.bind(('', 1234))
    tcpsocket.listen(5)
    while True:
        s, (ip, port) = tcpsocket.accept()
        threading.Thread(target = handler, args = (s,)).start()
  • Thanks for your response, @Aleksander Gurin. I added the crucial line `mySocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)` to my code above ... but am still seeing the same output. Am I overlooking something? Could it have to do with the use of threading (or lack thereof in my code)? – Pat Mar 15 '15 at 08:49
  • Also, I am still puzzled (maybe somewhat naively) by the fact that I have a server listening to a specific port but it doesn't receive all data sent to that port ... could anyone please explain where the posts sent by the second client end up or why they are not being received via the monitored port? – Pat Mar 15 '15 at 08:57
  • By the way, I just checked your code ... and it produces the same output as my code above, i.e.: the postings of client 2 are not received! – Pat Mar 15 '15 at 10:57
  • @Pat single-threaded server could handle only one client at a time (unless you use asynchronous socket handler). So in order to handle multiple clients you need one thread per client connection. Regarding my code example it works fine with your clients and do exactly what you want. – Aleksander Gurin Mar 15 '15 at 12:57
  • @ Aleksander Gurin: Thanks, Aleks! I just checked it again and everything works the way it should. Not sure where I went wrong when testing your code before. Thanks so much for going through the trouble of replying in detail. Your help is much appreciated! – Pat Mar 15 '15 at 16:14