zoukankan      html  css  js  c++  java
  • python的select服务端的代码和客户端的代码

    服务端的代码

    import socket
    import queue
    import select
    ip_bind = ("127.0.0.1",9000)
    
    message_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:
            print("waiting for new connection")
            stdinput,stdoutput,stderr = select.select(input_list,output_list,input_list,2)
            #开始select监听,对input_list中的服务端server进行监听
    
    
            for obj in stdinput:
                #判断是否有客户端连接进来,当有客户端连接进来时select将触发,就会进入循环
    
                if obj == server:  #代表一个新的连接进来
                    #判断当前触发的是不是服务端的对象,当触发的对象是服务端的对象时候,说明
                    #有新的客户端连接进来了
    
                    conn,addr = server.accept()
                    print("Client {0} is connected".format(addr))
                    conn.setblocking(False)
                    #把这个新连接的实例设置为非阻塞
    
                    #这个时候我们不能立即接受数据,因为在select中,是单线程的,如果这里直接开始接受数据,那么其他的客户端就无法连接进来了,所以只能
                    #先把这个链接存起来,放到一个input_list中,为什么放到input_list中呢,因为我们想监控这个链接,如果这个客户端有消息过来,那么select
                    #就会触发,如果没有数据返回,则select就不会被触发
    
                    input_list.append(conn)
                    #将和这个客户端的连接的服务端的实例也加入到监听列表中,当客户端发送消息的
                    #时候,select就会被触发
    
                    message_queue[conn] = queue.Queue()
                    #为这个连接的客户端单独创建一个独一无二的消息队列,用来保存客户端发送的消息。
    
    
                else:  #代表一个有数据的链接进来了,这个时候我就可以开始收数据了
    
                    #由于客户端连接进来时服务端接受客户端的连接请求,将这个客户端的服务端的
                    #也加入到监听列表中,这个客户端如果发送消息,则会触发select
                    try:
                        recv_data = obj.recv(1024)
                        if recv_data:
                            #客户端未断开
                            print("received {0} from client {1}".format(str(recv_data,encoding="utf-8"),addr))
    
                            #将收到的信息放入该客户端的队列中
                            message_queue[obj].put(recv_data)
    
                            #此时也不能直接给客户端返回数据,因为一旦返回数据,就又可能造成阻塞,所有将回复操作放到output列表中,让select监听
                            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))
    
            for sendobj in stdoutput: #这里处理的是返回的消息,output_list是我们自己维护的,我们自己往里面放数据
                try:
                    if not message_queue[sendobj].empty():
                    #如果消息队列中有消息,从消息队列中获取要发送的消息
                        send_data = message_queue[sendobj].get()
                        #从该客户端对象的消息队列中获取消息
                        sendobj.sendall(send_data)
                    else:
                        output_list.remove(sendobj)
                        #将监听移除等待瞎猜疑客户端发送消息
                except ConnectionResetError:
                    #客户端连接断开
                    del  message_queue[sendobj]
                    output_list.remove(sendobj)
                    print("Client {0} disconnected".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]
    

      

  • 相关阅读:
    洛谷 P6295
    洛谷 P4240
    洛谷 P3287
    My rating is 1064.
    洛谷 P5071
    C语言 #include <> 与 #include “” 区别
    C语言 #pragma once
    C语言 typedef 和 define 区别
    C语言 define 定义函数(多行书写)
    C语言 define 定义函数
  • 原文地址:https://www.cnblogs.com/bainianminguo/p/7468504.html
Copyright © 2011-2022 走看看