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