【问题标题】:how do i switch between connected clients with asyncio sockets我如何使用异步套接字在连接的客户端之间切换
【发布时间】:2022-01-14 20:00:04
【问题描述】:

我正在尝试制作一个套接字服务器,它能够使用 asyncio 套接字连接多个客户端,并且能够轻松地在它通信的客户端之间切换,同时仍然连接所有客户端。我以为会有某种类型的客户端 FD,比如在套接字中,但是我查看了文档并没有找到任何东西,或者我错过了。

这是我的服务器代码:

import socket
import asyncio


host = "localhost"

port = 9998

list_of_auths = ['desktop-llpeu0p\\tomiss', 'desktop-llpeu0p\\tomisss',
                 'desktop-llpeu0p\\tomissss', 'desktop-llpeu0p\\tomisssss']

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print('socket initiated.')
confirmed = 'CONFIRMED'
deny = 'denied'
#(so i dont forget) to get recv in async do: var = (await reader.read(4096)).decode('utf-8') if -1 then it will read all
#(so i dont forget) to write sendall do: writer.write(var.encode('utf-8')) should be used with await writer.drain()

async def handle_client(reader, writer):
    idrecv = (await reader.read(255)).decode('utf-8')
    if idrecv in list_of_auths:
        writer.write(confirmed.encode('utf-8'))
    else:
        writer.write(deny.encode('utf-8'))
        writer.close()
    request = None
    while request != 'quit':
        print("second checkpoint")

    writer.close()

async def run_server():
    print("first checkpoint")
    server = await asyncio.start_server(handle_client, host, port)
    async with server:
        await server.serve_forever()
asyncio.run(run_server())

此代码允许多个客户端同时连接;但是,它只能让我与最后一个连接的人进行通信。

【问题讨论】:

    标签: python python-3.x sockets


    【解决方案1】:

    我建议这样实现:

    class SocketHandler(asyncio.Protocol):
        def __init__(self):
            asyncio.Protocol.__init__(self)
            self.transport = None
            self.peername = None
            # your other code
    
        def connection_made(self, transport):
            """ incoming connection """
            global ALL_CONNECTIONS
            self.transport = transport
            self.peername = transport.get_extra_info('peername')
            ALL_CONNECTIONS.append(self)
            # your other code
    
        def connection_lost(self, exception):
            self.close()
            # your other code
    
        def data_received(self, data):
            # your code handling incoming data
        
    
        def close(self):
            try:
                self.transport.close()
            except AttributeError:
                pass
    
    
    # global list to store all connections
    ALL_CONNECTIONS = []
    
    def send_to_all(message):
        """ sending a message to all connected clients """
        global ALL_CONNECTIONS
        for sh in ALL_CONNECTIONS:
            # here you can also check sh.peername to know which client it is
            if sh.transport is not None:
                sh.transport.write(message)
    
    
    port = 5060
    loop = asyncio.get_event_loop()
    coro = loop.create_server(SocketHandler, '', port)
    server = loop.run_until_complete(coro)
    loop.run_forever()
    

    这样,到服务器的每个连接都由SocketHandler 的实例表示。每当您在此实例中处理一些数据时,您就知道它是哪个客户端连接。

    【讨论】:

    • 一旦我拥有了大约 4 个客户端的全局列表,编写器函数的代码是什么?
    • 成功了,谢谢
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多