<p>当不同的客户机彼此独立时,多线程处理是很好的:您编写代码时就好像只有一个客户机,然后为每个客户机启动一个线程。在</p>
<p>但是在这里,来自一个客户的信息必须发送给其他客户。每个客户端一个线程肯定会导致同步噩梦。所以让我们呼叫<code>select</code>去营救!<code>select.select</code>允许轮询套接字列表,并在套接字就绪后立即返回。在这里,您只需构建一个包含侦听套接字和所有可接受套接字的列表(该部分最初为空…):</p>
<ul>
<li>当侦听套接字准备好读取时,接受一个新的套接字并将其添加到列表中</li>
<li>当另一个套接字准备好读取时,从中读取一些数据。如果读取0字节,则其对等端已关闭或关闭:关闭它并将其从列表中删除</li>
<li>如果您从一个可接受的套接字中读取了某些内容,请在列表上循环,跳过侦听套接字和从中读取数据并将数据发送给其他套接字的套接字</li>
</ul>
<p>代码可以是(或多或少):</p>
<pre><code> main = socket.socket() # create the listening socket
main.bind((addr, port))
main.listen(5)
socks = [main] # initialize the list and optionaly count the accepted sockets
count = 0
while True:
r, w, x = select.select(socks, [], socks)
if main in r: # a new client
s, addr = main.accept()
if count == mx: # reject (optionaly) if max number of clients reached
s.close()
else:
socks.append(s) # appends the new socket to the list
elif len(r) > 0:
data = r[0].recv(1024) # an accepted socket is ready: read
if len(data) == 0: # nothing to read: close it
r[0].close()
socks.remove(r[0])
else:
for s in socks[1:]: # send the data to any other socket
if s != r[0]:
s.send(data)
elif main in x: # close if exceptional condition met (optional)
break
elif len(x) > 0:
x[0].close()
socks.remove(x[0])
# if the loop ends, close everything
for s in socks[1:]:
s.close()
main.close()
</code></pre>
<p>您当然需要实现一种机制来要求服务器停止,并测试所有这些,但这应该是一个起点</p>