03网络编程从之异步服务器

# 这里异步服务器的实现是借助于select,有关select模块在我上边的博客中有体现。# zen_utils也是咱们本身写的一个脚本。也在上边的磨课中import select, zen_utils,queue,timedef serve(listener,inpouts,outputs,message_queues):    while inputs:        print('等待开始第一个线程链接1111')        # 开始select监听,对input_list中的服务器端的server开始进行监听        # 一旦调用socket的send,recv函数,将会再次调用此模块        # 这里监控三个参数,第一个返回的是可读的list, 第二个存储的是可写的list, 第三个存储的是错误信息的        readable, writeable, errorinfo = select.select(inputs, outputs, inputs)        # 这里判断的是有没有客户端进行链接。        for s in readable:            # 而后在进行判断是服务端触发的链接仍是客户端触发的连接。            if s is listener:                # 接收的消息和客户端的IP端口                print(s)                connection, client_address = s.accept()                print('client:', connection, client_address)                # 设置为非阻塞模式。                connection.setblocking(0)                # 将客户端链接也加入到inputs监听列表中。                inputs.append(connection)                # 加入到要发送的消息队列中。                message_queues[connection] = queue.Queue()            else:                # 这是客户端发送消息触发的请求。                data = s.recv(1024)                if data != b'?' and data != b'':                    print('客户端{}发送了{}消息', s.getpeername(), data.decode('utf-8'))                    # 将接收到的消息须要进行回复的答案。放到对应的消息队列中。                    print(zen_utils.aphorisms.get(data,b''))                    message_queues[s].put(zen_utils.aphorisms.get(data,b''))                    if s not in outputs:                        outputs.append(s)                else:                    print("一个客户端断开了链接", client_address)                    # 输出端不在监听。                    if s in outputs:                        outputs.remove(s)                    # 输入端再也不监听                    inputs.remove(s)                    # 关闭这个套接字。                    s.close()                    # 删除消息队列中的消息                    del message_queues[s]        # 下边是处理输出。        for s in writeable:            try:                message_queue = message_queues.get(s)                sent_data = ''                if message_queue is not None:                    # 若是消息队列为空,不阻塞                    sent_data = message_queue.get_nowait()                else:                    # 这里触发的客户端关闭链接。                    print('客户端关闭链接')            except queue.Empty:                # 客户端发送完了消息。                print('%s' % s.getpeername())                outputs.remove(s)            else:                if sent_data != '':                    s.sendall(sent_data)                else:                    print('客户端关闭链接')            # 处理异常状况。            for s in errorinfo:                print('有一个异常客户端的链接', s.getpeername())                inputs.remove(s)                if s in outputs:                    outputs.remove(s)                s.close()                del message_queues[s]        time.sleep(1)if __name__ == '__main__':    address = zen_utils.parse_command_line('获取IP端口')    listener = zen_utils.create_srv_socket(address)    # 将定义好的一个套接字传入到列表中。    inputs = [listener]    # 处理要发送的数据。    outputs = []    # 要发送的数据    message_queues = {}    serve(listener,inputs,outputs,message_queues)
相关文章
相关标签/搜索