Python SocketServer:发送到多个客户端?

发布于 2021-01-29 18:24:06

好吧,我正在尝试使用SocketServer构建一个小型python
prgram,该服务器应该将其接收的消息发送给所有连接的客户端。我被困住了,我不知道如何在服务器端存储客户端,也不知道如何发送到多个客户端。哦,我的程序每次连接1个以上的客户端时失败,并且每次客户端发送的1条以上消息都失败…

到目前为止,这是我的代码:

        print str(self.client_address[0])+' connected.'
    def handle(self):
        new=1
        for client in clients:
            if client==self.request:
                new=0
        if new==1:
            clients.append(self.request)
        for client in clients:
            data=self.request.recv(1024)
            client.send(data)

class Host:
    def __init__(self):
        self.address = ('localhost', 0)
        self.server = SocketServer.TCPServer(self.address, EchoRequestHandler)
        ip, port = self.server.server_address
        self.t = threading.Thread(target=self.server.serve_forever)
        self.t.setDaemon(True)
        self.t.start()
        print ''
        print 'Hosted with IP: '+ip+' and port: '+str(port)+'. Clients can now connect.'
        print ''
    def close(self):
        self.server.socket.close()

class Client:
    name=''
    ip=''
    port=0
    def __init__(self,ip,port,name):
        self.name=name
        self.hostIp=ip
        self.hostPort=port
        self.s=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.s.connect((self.hostIp, self.hostPort))
    def reco(self):
        self.s=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.s.connect((self.hostIp, self.hostPort))
    def nick(self,newName):
        self.name=newName
    def send(self,message):
        message=self.name+' : '+message
        len_sent=self.s.send(message)
        response=self.s.recv(len_sent)
        print response
        self.reco()
    def close(self):
        self.s.close()

显然,我不知道自己在做什么,所以任何帮助都将非常有用。
提前致谢!

编辑:我在Windows Vista上使用Python 2.7。

关注者
0
被浏览
154
1 个回答
  • 面试哥
    面试哥 2021-01-29
    为面试而生,有面试问题,就找面试哥。

    您想在这里查看asyncore。您正在客户端调用的套接字操作被阻止(在接收到一些数据或发生超时之前不会返回),这使得很难侦听主机发送的消息,并使客户端实例排队将数据发送到同一时间。异步应该从您那里抽象出基于超时的轮询循环。

    这是代码“样本”-如果有任何不清楚的地方,请告诉我:

    from __future__ import print_function
    
    import asyncore
    import collections
    import logging
    import socket
    
    
    MAX_MESSAGE_LENGTH = 1024
    
    
    class RemoteClient(asyncore.dispatcher):
    
        """Wraps a remote client socket."""
    
        def __init__(self, host, socket, address):
            asyncore.dispatcher.__init__(self, socket)
            self.host = host
            self.outbox = collections.deque()
    
        def say(self, message):
            self.outbox.append(message)
    
        def handle_read(self):
            client_message = self.recv(MAX_MESSAGE_LENGTH)
            self.host.broadcast(client_message)
    
        def handle_write(self):
            if not self.outbox:
                return
            message = self.outbox.popleft()
            if len(message) > MAX_MESSAGE_LENGTH:
                raise ValueError('Message too long')
            self.send(message)
    
    
    class Host(asyncore.dispatcher):
    
        log = logging.getLogger('Host')
    
        def __init__(self, address=('localhost', 0)):
            asyncore.dispatcher.__init__(self)
            self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
            self.bind(address)
            self.listen(1)
            self.remote_clients = []
    
        def handle_accept(self):
            socket, addr = self.accept() # For the remote client.
            self.log.info('Accepted client at %s', addr)
            self.remote_clients.append(RemoteClient(self, socket, addr))
    
        def handle_read(self):
            self.log.info('Received message: %s', self.read())
    
        def broadcast(self, message):
            self.log.info('Broadcasting message: %s', message)
            for remote_client in self.remote_clients:
                remote_client.say(message)
    
    
    class Client(asyncore.dispatcher):
    
        def __init__(self, host_address, name):
            asyncore.dispatcher.__init__(self)
            self.log = logging.getLogger('Client (%7s)' % name)
            self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
            self.name = name
            self.log.info('Connecting to host at %s', host_address)
            self.connect(host_address)
            self.outbox = collections.deque()
    
        def say(self, message):
            self.outbox.append(message)
            self.log.info('Enqueued message: %s', message)
    
        def handle_write(self):
            if not self.outbox:
                return
            message = self.outbox.popleft()
            if len(message) > MAX_MESSAGE_LENGTH:
                raise ValueError('Message too long')
            self.send(message)
    
        def handle_read(self):
            message = self.recv(MAX_MESSAGE_LENGTH)
            self.log.info('Received message: %s', message)
    
    
    if __name__ == '__main__':
        logging.basicConfig(level=logging.INFO)
        logging.info('Creating host')
        host = Host()
        logging.info('Creating clients')
        alice = Client(host.getsockname(), 'Alice')
        bob = Client(host.getsockname(), 'Bob')
        alice.say('Hello, everybody!')
        logging.info('Looping')
        asyncore.loop()
    

    结果如下:

    INFO:root:Creating host
    INFO:root:Creating clients
    INFO:Client (  Alice):Connecting to host at ('127.0.0.1', 51117)
    INFO:Client (    Bob):Connecting to host at ('127.0.0.1', 51117)
    INFO:Client (  Alice):Enqueued message: Hello, everybody!
    INFO:root:Looping
    INFO:Host:Accepted client at ('127.0.0.1', 55628)
    INFO:Host:Accepted client at ('127.0.0.1', 55629)
    INFO:Host:Broadcasting message: Hello, everybody!
    INFO:Client (  Alice):Received message: Hello, everybody!
    INFO:Client (    Bob):Received message: Hello, everybody!
    


知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看