简体   繁体   English

具有多个客户端的简单服务器

[英]simple server with multiple clients

I'm trying to implement simple server with multiple clients. 我正在尝试实现具有多个客户端的简单服务器。 It should receive data from necessary socket, process and then send data to other clients. 它应该从必要的套接字接收数据,进行处理,然后将数据发送给其他客户端。 I use select module from Python standard library. 我使用Python标准库中的select模块。 Here's server: 这是服务器:

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)

Here's simple client: 这是简单的客户端:

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

Receiving part of server works fine, but server doesn't produce any output. 接收服务器的一部分工作正常,但是服务器不产生任何输出。 I'm not experienced in network programming at all and It feels like I'm missing something. 我完全没有网络编程经验,感觉好像我缺少什么。

Yeah...use zeromq instead: 是的...改用zeromq

server.py 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 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()

There are a few things that seem odd in your script. 您的脚本中有些事情看起来很奇怪。

The standard usage of the select module is the following: you have one socket to listen to connections, and one socket per connection with the clients. select模块的标准用法如下:您有一个套接字来监听连接,每个与客户端的连接都有一个套接字。

At first, only this socket is added to your potential readers list and your potential writers list is empty. 首先,仅将此套接字添加到您的潜在读者列表,而您的潜在作家列表为空。

Calling select.select(potential_readers, potential_writers, potential_errors) will return 3 lists: - Sockets ready for reading - Sockets ready for writing - Sockets in error 调用select.select(potential_readers,potential_writers,potential_errors)将返回3个列表:-准备读取的套接字-准备写入的套接字-错误的套接字

In the list of sockets ready for reading, if the socket is the one listening for the connection, it must accept it and put the new socket in the potential reads, potential writes and potential errors. 在准备读取的套接字列表中,如果套接字是正在监听连接的套接字,则它必须接受该套接字并将新套接字放入潜在的读取,潜在的写入和潜在的错误中。

If the socket is another one then, there is data to read from this socket. 如果该套接字是另一个套接字,则有数据要从该套接字读取。 You shoud make a call to sock.recv(length) 你应该打电话给sock.recv(length)

If you want to send data, you should send it from your wlist returned by select.select. 如果要发送数据,则应从select.select返回的wlist中发送数据。

The errlist is not used very often. errlist并不经常使用。


Now, for the solution for your problem, the way you describe your protocol (if I understood well), it might look like this: 现在,对于您的问题的解决方案,即您描述协议的方式(如果我理解得很好),可能看起来像这样:

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)

I haven't tested this code so there might be a few errors, but this is close to how I would do it. 我尚未测试此代码,因此可能会出现一些错误,但这与我的操作方式很接近。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM