Python TCP 服务器使用 select()
Python TCP Server using select()
这是我的第一个条目@Whosebug;-))
我需要一个 Python3 TCP 服务器,它将客户端的所有输入发送给其他参与者。服务器工作,但不幸的是,消息只返回给发送客户端。一旦第二个客户端发送内容,它就会获得所有 entries.The 个条目,因此在输出队列中可用。
为什么条目无法被select()识别?
感谢支持。
`
import select
import socket
import sys
import queue
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.setblocking(0)
server_address = ('192.168.100.28', 8888)
print ("starting up on %s port %s" % server_address)
server.bind(server_address)
server.listen(5)
inputs = [ server ]
outputs = [ ]
message_queues = {}
while inputs:
print ("\nwaiting for the next event")
readable, writable, exceptional = select.select(inputs, outputs, inputs)
处理输入
for s in readable:
if s is server:
# A "readable" server socket is ready to accept a connection
connection, client_address = s.accept()
print ("new connection from", client_address)
connection.setblocking(0)
inputs.append(connection)
# Give the connection a queue for data we want to send
message_queues[connection] = queue.Queue()
else:
data = s.recv(1024)
if data:
# A readable client socket has data
print ('received "%s" from %s' % (data, s.getpeername()))
# Add output channel for response
#message_queues[s].put(data)
if s not in outputs:
outputs.append(s)
for aQueue in message_queues:
message_queues[aQueue].put(data)
# AQueue.send ("Test".encode())
else:
# Interpret empty result as closed connection
print ("closing", client_address, "after reading no data")
# Stop listening for input on the connection
if s in outputs:
outputs.remove(s)
inputs.remove(s)
s.close()
# Remove message queue
del message_queues[s]
处理输出
for s in writable:
try:
next_msg = message_queues[s].get_nowait()
except queue.Empty:
# No messages waiting so stop checking for writability.
print ("output queue for", s.getpeername(), "is empty")
outputs.remove(s)
else:
print ('sending "%s" to %s' % (next_msg, s.getpeername()))
s.send(next_msg)
处理“异常情况”
for s in exceptional:
print ("handling exceptional condition for", s.getpeername())
# Stop listening for input on the connection
inputs.remove(s)
if s in outputs:
outputs.remove(s)
s.close()
# Remove message queue
del message_queues[s]
`
你的问题是当你从 output
列表中读取内容时,你只添加了一个对等点。当您向其消息队列写入内容时,您应该这样做。
接收部分应该变成:
...
data = s.recv(1024)
if data:
# A readable client socket has data
print ('received "%s" from %s' % (data, s.getpeername()))
# Add output channel for response
#message_queues[s].put(data)
# if s not in outputs:
# outputs.append(s)
for aQueue in message_queues:
message_queues[aQueue].put(data)
if aQueue not in outputs: # enqueue the msg
outputs.append(aQueue) # and ask select to warn when it can be sent
# AQueue.send ("Test".encode())
else:
...
根据您自己的要求,您应该只为其他参与者排队消息:
for aQueue in message_queues:
if aQueue != s: # only send to other participants
...
最后,您经常测试 outputs
中是否存在套接字。让我们认为 set
比 list
.
更合适
这是我的第一个条目@Whosebug;-))
我需要一个 Python3 TCP 服务器,它将客户端的所有输入发送给其他参与者。服务器工作,但不幸的是,消息只返回给发送客户端。一旦第二个客户端发送内容,它就会获得所有 entries.The 个条目,因此在输出队列中可用。
为什么条目无法被select()识别?
感谢支持。
`
import select
import socket
import sys
import queue
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.setblocking(0)
server_address = ('192.168.100.28', 8888)
print ("starting up on %s port %s" % server_address)
server.bind(server_address)
server.listen(5)
inputs = [ server ]
outputs = [ ]
message_queues = {}
while inputs:
print ("\nwaiting for the next event")
readable, writable, exceptional = select.select(inputs, outputs, inputs)
处理输入
for s in readable:
if s is server:
# A "readable" server socket is ready to accept a connection
connection, client_address = s.accept()
print ("new connection from", client_address)
connection.setblocking(0)
inputs.append(connection)
# Give the connection a queue for data we want to send
message_queues[connection] = queue.Queue()
else:
data = s.recv(1024)
if data:
# A readable client socket has data
print ('received "%s" from %s' % (data, s.getpeername()))
# Add output channel for response
#message_queues[s].put(data)
if s not in outputs:
outputs.append(s)
for aQueue in message_queues:
message_queues[aQueue].put(data)
# AQueue.send ("Test".encode())
else:
# Interpret empty result as closed connection
print ("closing", client_address, "after reading no data")
# Stop listening for input on the connection
if s in outputs:
outputs.remove(s)
inputs.remove(s)
s.close()
# Remove message queue
del message_queues[s]
处理输出
for s in writable:
try:
next_msg = message_queues[s].get_nowait()
except queue.Empty:
# No messages waiting so stop checking for writability.
print ("output queue for", s.getpeername(), "is empty")
outputs.remove(s)
else:
print ('sending "%s" to %s' % (next_msg, s.getpeername()))
s.send(next_msg)
处理“异常情况”
for s in exceptional:
print ("handling exceptional condition for", s.getpeername())
# Stop listening for input on the connection
inputs.remove(s)
if s in outputs:
outputs.remove(s)
s.close()
# Remove message queue
del message_queues[s]
`
你的问题是当你从 output
列表中读取内容时,你只添加了一个对等点。当您向其消息队列写入内容时,您应该这样做。
接收部分应该变成:
...
data = s.recv(1024)
if data:
# A readable client socket has data
print ('received "%s" from %s' % (data, s.getpeername()))
# Add output channel for response
#message_queues[s].put(data)
# if s not in outputs:
# outputs.append(s)
for aQueue in message_queues:
message_queues[aQueue].put(data)
if aQueue not in outputs: # enqueue the msg
outputs.append(aQueue) # and ask select to warn when it can be sent
# AQueue.send ("Test".encode())
else:
...
根据您自己的要求,您应该只为其他参与者排队消息:
for aQueue in message_queues:
if aQueue != s: # only send to other participants
...
最后,您经常测试 outputs
中是否存在套接字。让我们认为 set
比 list
.