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

标签 python sockets networking

我正在尝试实现具有多个客户端的简单服务器。它应该从必要的套接字接收数据,处理然后将数据发送到其他客户端。我使用 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()

服务器的接收部分工作正常,但服务器不产生任何输出。 我根本没有网络编程经验,感觉好像我错过了一些东西。

最佳答案

您的脚本中有些事情看起来很奇怪。

select 模块的标准用法如下:您有一个套接字来监听连接,每个与客户端的连接都有一个套接字。

首先,只有此套接字会添加到您的潜在读者列表中,而您的潜在作者列表为空。

调用 select.select(潜在的读者, 潜在的作家, 潜在的错误) 将返回 3 个列表: - 可供读取的套接字 - 套接字准备好写入 - 套接字错误

在准备读取的套接字列表中,如果该套接字是正在监听连接的套接字,则它必须接受该连接并将新套接字放入潜在的读取、潜在的写入和潜在的错误中。

如果套接字是另一个套接字,则可以从该套接字读取数据。你应该调用 sock.recv(length)

如果你想发送数据,你应该从 select.select 返回的 wlist 中发送它。

errlist 不经常使用。


现在,为了解决您的问题,您描述协议(protocol)的方式(如果我理解得很好)可能如下所示:

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)

我尚未测试此代码,因此可能存在一些错误,但这与我的做法很接近。

关于python - 具有多个客户端的简单服务器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7162578/

相关文章:

python - 如何在 Python 中修复此 unicode/cPickle 错误?

python - TreeMap 路径中二进制字符串的表示

python - 使用 Internet Explorer 访问 Twisted Server 发送事件

c++ - 创建一个基本的 C/C++ TCP 套接字编写器

python - 具有中央中继服务器的多线程套接字

聊天服务器和客户端实现?

python - 使用 ORB 的 OpenCV 图像对齐

.net - 在 .NET 中进行保持事件套接字检查的最佳方法是什么?

networking - 从网络位计数转换为网络掩码的最佳方法是什么?

python - SO_REUSEPORT 可以用在 Unix 域套接字上吗?