我正在尝试使用多个客户端实现简单的服务器。它应该从必要的套接字,进程接收数据,然后将数据发送到其他客户端。我使用Python标准库中的select模块。 这是服务器:
class ProcessingServer:
def __init__(self, bindaddress="localhost", portname=50001, maxqueue=5):
self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.socket.bind((bindaddress, portname))
self.socket.listen(maxqueue)
self.inputsocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.data = ""
def connect_to_output(self, address, port):
self.inputsocket.connect((address, port))
def start(self):
rsocks = []
wsocks = []
rsocks.append(self.socket)
wsocks.append(self.inputsocket)
self.socket.accept()
while True:
try:
reads, writes, errs = select.select(rsocks, wsocks, [])
except:
return
for sock in reads:
if sock == self.socket:
client, address = sock.accept()
rsocks.append(client)
else:
self.socket.send(self.data)
rsocks.remove(sock)
for sock in writes:
if sock == self.inputsocket:
self.data = sock.recv(512)
wsocks.remove(sock)
print repr(self.data)
这是简单的客户:
import socket
mysocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
mysocket.connect(("localhost", 50001))
while True:
data = mysocket.recv(512)
print repr(data)
mysocket.close()
接收部分服务器工作正常,但服务器不产生任何输出。 我根本没有网络编程经验,感觉我错过了什么。
答案 0 :(得分:2)
是啊......改为使用zeromq:
server.py
import zmq
context = zmq.Context()
socket = context.socket(zmq.REP)
socket.bind("tcp://127.0.0.1:50001")
while True:
msg = socket.recv()
print "Got", msg
socket.send(msg)
client.py
import zmq
context = zmq.Context()
socket = context.socket(zmq.REQ)
socket.connect("tcp://127.0.0.1:50001")
for i in range(100):
msg = "msg %s" % i
socket.send(msg)
print "Sending", msg
msg_in = socket.recv()
答案 1 :(得分:2)
你的剧本中有一些看似奇怪的东西。
select模块的标准用法如下:您有一个用于侦听连接的套接字,以及每个与客户端连接的一个套接字。
首先,只有此套接字会添加到您的潜在读者列表中,并且您的潜在作者列表为空。
调用select.select(potential_readers,potential_writers,potential_errors)将返回3个列表: - 插座准备好阅读 - 插座准备写入 - 错误的套接字
在准备好读取的套接字列表中,如果套接字是监听连接的套接字,它必须接受它并将新套接字置于潜在读取,潜在写入和潜在错误中。
如果套接字是另一个套接字,则有从该套接字读取的数据。你应该打电话给sock.recv(长度)
如果您想发送数据,您应该从select.select返回的wlist发送数据。
错误列表不经常使用。
现在,对于您的问题的解决方案,您描述协议的方式(如果我理解得很好),它可能看起来像这样:
import socket, select
sock_producer = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock_producer.bind(('localhost', 5000))
sock_producer.listen(5)
producers = []
clients = []
sock_consumer_listener = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# Note: different port to differentiate the clients who receive data from the one who sends messages
sock_consumer_listener.bind(('localhost', 5001))
rlist = [sock_producer, sock_listener]
wlist = []
errlist = []
out_buffer = []
while True:
r, w, err = select.select(rlist, wlist, errlist)
for sock in r:
if sock == sock_producer:
prod, addr = sock.accept()
producers.append(prod)
rlist.append(prod)
elif sock == sock_consumer_listener:
cons, addr = sock.accept()
clients.append(cons)
wlist.append(cons)
else:
out_buffer.append(sock.recv(1024))
out_string = ''.join(out_buffer)
out_buffer = []
for sock in w:
if sock in clients:
sock.send(out_string)
我没有测试过这段代码,因此可能会出现一些错误,但这与我的做法非常接近。