Python: 客户端-服务器通信 - 如何在同一服务器端口上同时接收来自不同客户端的消息?

Python: Client-Server Communication - How to receive messages from different clients on the same server port simultaneously?

我正在研究客户端-服务器架构,其中多个客户端应将文件传输到 运行 服务器。我想知道服务器是否可以同时从一个端口接收来自不同客户端的输入。

到目前为止我的代码:

服务器

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 = ''

客户端

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

我正在启动客户端的两个实例,如下所示:

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

然而,到目前为止,我的服务器只接收来自一个客户端的输入:

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.<
...

因此我的问题是:是否也可以从服务器上的第二个客户端接收帖子 - 如果可以,如何接收?

P. S.:我检查了 this related SO post 但也无法真正从中提取答案。

bind 套接字之前,您需要设置 SO_REUSEADDR 套接字选项。这就是所谓的socket-level option。结果服务器会像这样锁定:

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()