第十一章:网络通信-selectors:IO多路复用抽象-回送服务器

    xiaoxiao2024-10-20  82

    11.3.2 回送服务器 这里给出的回送服务器例子使用了Selectorkey中的应用数据来注册发生新事件时要调用的一个回调函数。主循环从键得到这个回调,并把套接字和事件掩码传递给该回调。服务器启动时,其会注册当主服务器套接字上发送读事件时要调用的accept()函数。接受连接会产生一个新的套接字,然后注册read()函数作为读事件的一个回调。

    import selectors import socket mysel = selectors.DefaultSelector() keep_running = True def read(connection,mask): "Call back for read events" global keep_running client_address = connection.getpeername() print('read({})'.format(client_address)) data = connection.recv(1024) if data: # A readable client socket has data. print(' received {!r}'.format(data)) connection.sendall(data) else: # Interpret empty result as closed connection. print(' closing') mysel.unregister(connection) connection.close() # Tell the main loop to stop. keep_running = False def accept(sock,mask): "Callback for new connections" new_connection,addr = sock.accept() print('accept({})'.format(addr)) new_connection.setblocking(False) mysel.register(new_connection,selectors.EVENT_READ,read) server_address = ('localhost',10000) print('starting up on {} port {}'.format(*server_address)) server = socket.socket(socket.AF_INET,socket.SOCK_STREAM) server.setblocking(False) server.bind(server_address) server.listen(5) mysel.register(server,selectors.EVENT_READ,accept) while keep_running: print('waiting for I/O') for key,mask in mysel.select(timeout=1): callback = key.data callback(key.fileobj,mask) print('shutting down') mysel.close()

    如果read()没有从套接字接收到任何数据,那么当连接的另一端关闭时,它会中断读事件而不是发送数据。之后,会从选择器删除这个套接字,并将其关闭。由于这只是一个示例程序,所以这个服务器与唯一的客户结束通信后还会关闭服务器自身。

    最新回复(0)