Service-side code
Import Socketimport Queueimport Selectip_bind = ("127.0.0.1", 9000) Message_queue = {} #保存客户端发送过来的信息, putting messages into the queue input_list = []output_list = []if __name__ = = ' __main__ ': Server = Socket.socket () server.bind (Ip_bind) Server.listen (10) Server.setblocking (False) #设置socket服务端为非阻塞的 input_list.append (server) #初始化将服务端加入到监听列表中 while True:pri NT ("Waiting for New Connection") Stdinput,stdoutput,stderr = Select.select (input_list,output_list,input_list,2) #开始select监听, the service-side server in input_list is listening for obj in stdinput: #判断是否有客户端连接进来, when a client connection comes in, select fires and goes into the loop If obj = = Server: #代表一个新的连接进来 #判断当前触发的是不是服务端的对象, when the object being triggered is the object of the server, the description #有新的客户端连接进来了 CONN,ADDR = Server.accept () print ("Client {0} is connected". Format (addr)) CO Nn.setblocking (False) #把这个新连接的实例设置为非阻塞 #这个时候我们不能立即接受数据, because in Select, is single-threaded, if the data is directly started here, then other customers The end cannot be connected, so you can only #先把这个链接存起来, put in a input_list, why put in input_list, because we want to monitor this link, if the client has a message, then select #就会触发, if there is no data returned, then select will not be Trigger Input_list.append (conn) #将和这个客户端的连接的服务端的实例也加入到监听列表中, when the client sends the #时候 of the message, select will is triggered message_queue[conn] = queue. Queue () #为这个连接的客户端单独创建一个独一无二的消息队列 to hold messages sent by the client. else: #代表一个有数据的链接进来了, this time I can start to collect the data #由于客户端连接进来时服务端接受客户端的连接请求, will this client server side of the #也加入到监听列表中, this client if Sending a message, the Select try:recv_data = OBJ.RECV (1024x768) If Recv_data is triggered: #客户端未断开 Print ("received {0} from client {1}". Format (str (recv_data,encoding= "Utf-8") , addr)) #将收到的信息放入该客户端的队列中 Message_queue[obj].put (Recv_data) #此时也不能直接给客户端返回数据, because once the data is returned, it can cause blocking, all of which put the reply action in the output list, let select Listen if obj not in output_list: Output_list.append (obj) except ConnectionResetError:input_list.remove (obj) Del Message_queue[obj] Print ("Client {0} is disconnected". Format (addr)) to Sendobj in S Tdoutput: #这里处理的是返回的消息, Output_list is our own maintenance, we put the data inside the Try:if not Message_queue[sendobj].empty () : #如果消息队列中有消息, gets the message to be sent from the message queue Send_data = Message_queue[sendobj].get () #从该客户端对象的消息队列中获取消息 Sendobj.sendall (send_data) Else:output_list.remo ve (sendobj) #将监听移除等待瞎猜疑客户端发送消息 except Connectionreseterror: #客户端连接断开 Del Message_queue[sendobj] Output_list.remove (sendobj) print ("Client {0} disconnecte D ". Format (addr)) for obj in stderr: #如果出错的处理 # Print () input_list.remove (obj) if Obj in Output_list: Output_list.remove (obj) obj.close () del Message_queue[obj]
Python's Select server-side code and the client's code