# can_read, can_write, _ = select.select(inputs, outputs, None, None) # # 第一个主要参数是大家必须监听可写的套接字, 第二个主要参数是大家必须监听应写的套接字, 第三个主要参数使大家必须监听出现异常的套接字, 第四个则是时间限制设定. # # 假如监听的套接字考虑了可写应写标准, 那麼所回到的can,read 或者 can_write便会有值了, 随后大家就可以运用这种返回值开展接着的实际操作了。相较为unix 的select实体模型, 其select涵数的返回值是一个整形, 用于分辨是不是实行取得成功. # # 第一个主要参数便是服务端的socket, 第二个是我们在运作全过程中储存的客户端的socket, 第三个储存错误报告 。 # 关键是在返回值, 第一个回到的是可写的list, 第二个储存的是应写的list, 第三个储存的是错误报告的 # list。 import select, socket, queue from time import sleep # 造就一个 TCP/IP联接 server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 设定socket为多线程方式。 server.setblocking(False) # 关联IP地址和端口号 # 建立一个IP ,端口号,当地IP server_address = ('localhost', 8090) print('starting up on %s port %s' % server_address) # 关联IP和端口号 server.bind(server_address) # 设定服务器端监听总数 server.listen(3) inputs = [server] # 解决要发送的数据信息 outputs = [] # 輸出的消息序列 message_queues = {} while inputs: # 等候最少一个联接刚开始启用进程 print("waiting for the next event") # 刚开始select监听,对input_list中的服务端的server刚开始开展监听 # 一旦启用socket的send ,recv涵数,可能再度启用此控制模块 # 这儿监管三个主要参数,第一个回到的是可写的list, 第二个储存的是应写的list, 第三个储存的是错误报告的 readable, writable, exceptional = select.select(inputs, outputs, inputs) # 解决键入 # 循环系统分辨是不是有客户端联接进去 ,当有客户端联接进去的情况下select将开展开启 for s in readable: # 分辨当今开启的是并不是服务器端目标,当开启的是服务器端目标, 表明有新的客户端联接进来了 if s is server: # 和客户端创建联接 connection, client_address = s.accept() # 复印客户端的连接 print('connection from', client_address) # 设定socket为多线程方式 。 connection.setblocking(0) # 将客户端目标也添加到监听列表中 ,当客户端发送消息的情况下select也会开启。 inputs.append(connection) # 为联接的客户端独立创建一个消息序列,用于储存客户端发送的消息 message_queues[connection] = queue.Queue() else: # 有老客户发送消息,解决接受 # 因为客户端联接进去的情况下服务器端接受客户端的要求,将客户端也添加来到监听列表。 # 客户端发送的消息将开启 。 # 分辨开启目标是不是为客户端 # 接受客户端的信息内容 data = s.recv(1024) # 客户端沒有断掉 if data != '': # 一个能用的客户端发送了数据信息 print('received "%s" from %s' % (data, s.getpeername())) # 将接纳到的消息放进相匹配的客户端的消息序列中 message_queues[s].put(data) # 将必须开展回应实际操作的socket放进output列表中 ,让select监听 # 这儿大家假如接到消息将服务器端加上进到輸出列表。 # 随后select便会监听到, if s not in outputs: outputs.append(s) else: # 客户端被监听到有转变,并不是有客户端传出去的消息 ,便是客户端断掉了。 # 客户端断掉了联接,将客户端的监听从input列表中清除 print('closing', client_address) if s in outputs: outputs.remove(s) inputs.remove(s) s.close() # 清除相匹配的socket客户端目标的消息序列 del message_queues[s] # 解决輸出 。 # 假如如今沒有客户端的要求,都没有客户端发送消息时 ,刚开始对发送的消息列表开展解决。 # 分辨是不是必须发送消息。 # 储存哪一个客户端发送了消息。 for s in writable: try: # 假如消息序列中有消息,就从消息序列中获得要发送的消息 。 message_queue = message_queues.get(s) sent_data = '' if message_queues is not None: # 假如队列入空得话不一(堵塞) send_data = message_queue.get_nowait() else: # 客户端中断连接了 print('has closed') # 假如队列入空得话,就意味着着发送的消息完后 ,就必须从序列中删掉。 except queue.Empty: print('%s' % (s.getpeername())) outputs.remove(s) else: # print "sending %s to %s " % (send_data, s.getpeername) # print "send something" if message_queue is not None: s.send(send_data) else: print("has closed ") # del message_queues[s] # writable.remove(s) # print "Client %s disconnected" % (client_address) # # Handle "exceptional conditions" # 解决出现异常的状况 # 如果有异常现象,那麼就从輸出序列中删掉,随后关掉联接。 for s in exceptional: print('exception condition on', s.getpeername()) # Stop listening for input on the connection inputs.remove(s) if s in outputs: outputs.remove(s) s.close() # Remove message queue del message_queues[s] sleep(1)
文章来源于网络 ,如有侵权请联系站长QQ61910465删除
收藏 | 0 点赞 | 0 打赏
生成海报
本文版权归QU快排Www.seoGurubLog.com 所有,如有转发请注明来出,竞价开户托管,seo优化请联系QQ▲61910465