博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
python的select服务端的代码和客户端的代码
阅读量:5805 次
发布时间:2019-06-18

本文共 3158 字,大约阅读时间需要 10 分钟。

服务端的代码

import socketimport queueimport selectip_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]

  

转载于:https://www.cnblogs.com/bainianminguo/p/7468504.html

你可能感兴趣的文章
文件查找
查看>>
shell编程前言(一)
查看>>
5、centos7.*配置yum的EPEL源及其它源
查看>>
JSON前后台简单操作
查看>>
shell中一些常见的文件操作符
查看>>
CentOS 7 装vim遇到的问题和解决方法
查看>>
JavaScript基础教程1-20160612
查看>>
使用第三方类、库需要注意的正则类RegexKitLite的使用
查看>>
iOS \U7ea2 乱码 转换
查看>>
FCN图像分割
查看>>
ios xmpp demo
查看>>
设计模式之-工厂模式、构造函数模式
查看>>
python matplotlib 中文显示参数设置
查看>>
数据库事务隔离级别
查看>>
os模块大全详情
查看>>
【ros】Create a ROS package:package dependencies报错
查看>>
从内积的观点来看线性方程组
查看>>
kali linux 更新问题
查看>>
HDU1576 A/B【扩展欧几里得算法】
查看>>
廖雪峰javascript教程学习记录
查看>>