文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Python:简单select模块使用

2023-01-31 01:50

关注

select 多并发socket 例子

#!/usr/bin/env python
#coding:utf-8

import select
import socket
import Queue


listen_addr=('0.0.0.0',8000)
#监听服务器
server=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
try:
    server.bind(listen_addr)
    server.setblocking(0)
except socket.error as e:
    print e
    exit(0)

server.listen(500)

print("starting up on %s port %s"%listen_addr)

inputs=[server,]  #监测服务器端,毕竟server本身也是一个fd,文件描述符

outputs=[]    #这里存放的是内核返回的活跃的客户端连接,就是服务器需给send data的客户端连接


message_queue={}

#开始循环监测事件
while True:
    print("waiting for next event...")   #

    readable,writeable,exceptionl=select.select(inputs,outputs,inputs)#如果没有任何fd就绪,那么程序一直会阻塞在这里
    "可以recv  可以send  exception"
    for s in readable:  #每一个s就是一个socket
        "处理新的客户端连接,并统一接受他们的数据"
        if s is server:   #由于上面我们server自己页当成一个fd放在了inputs列表里,传给了select,如果这个s是select代表这个fd就绪
            #如果server就绪,那就说明又有新的客户端的连接到了
            client,addr=s.accept()
            print("new connection from",addr)
            client.setblocking(0)

            """有客户端连接进来就把这个连接先放在select列表中,
                现在这些列表中的连接都会交给select去监听,如果列表中有一个客户端发来数据
                那么这个客户端所连接的对应fd就会转变成就绪状态,select就会将这个就绪状态的连接
                返回给用户程序的(即readable中)
                最后循环这个readable列表,取出这个连接,并只接受这些数据暂时存放
            """
            inputs.append(client)

            #往字典中添加一个队列用于暂时存放这个客户端连接传来的数据
            message_queue[client]=Queue.Queue()

        #如果不是server,那么就是原来连接的客户端有数据来了
        else:
            #接受
            data=s.recv(1024)
            if data:
                print("receive come from %s",s.getpeername()[0],data)
                message_queue[s].put(data)  #收到的数据先放到对应的queue中,一会返回数据给客户端
                if s not in outputs:
                    outputs.append(s)  #为了不影响处理与其他客户端的连接。这里不立刻返回数据给客户端, 先放着,等会一起处理发送数据

            else: #如果没有收到客户端的数据,表示客户端断开了
                print("client connection break")

                if s in outputs:
                    outputs.remove(s) #清除已经断开的连接,没不会有信息发送给客户端了
                inputs.remove(s)

                del message_queue[s]


    for s in writeable:   #现在处理没有处理完客户端连接,就是接着前面向客户端发送数据
        try:
            next_msg=message_queue[s].get_nowait() #从队列中删除这个项目并伴随没有阻塞的返回这个项目(get)

        except Queue.Empty:
            print("client [%s] ")%(s.getpeername()[0]),
            print("queue is empty")
            outputs.remove(s)

        else:
            print("sending msg to [%s]"%(s.getpeername()[0]),next_msg) #输出客户端的信息
            s.send(next_msg.upper())

    for s in exceptionl:   #处理出现异常的连接
        print("handling exception for",s.getpeername())
        inputs.remove(s)
        if s in outputs:
            outputs.remove(s)
        s.close()
        del message_queue[s]

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯