Python的Select模块

Python中的select模块专注于I/O多路复用,提供了select poll epoll三个方法(其中后两个在Linux中可用,windows仅支持select),另外也提供了kqueue方法(freeBSD系统),select 方法允许你响应不同 socket 的多个事件以及其它不同事件。例如你可以让 select 在某个 socket 有数据到达时,或者当某个 socket 可以写数据时,又或者是当某个 socket 发生错误时通知你,好处是你可以同时响应很多 socket 的多个事件。

select 方法的三个参数都是 list 类型,分别代表读事件、写事件、错误事件,同样方法返回值也是三个 list,包含的是哪些事件(读、写、异常)满足了

简单使用:

服务端:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2017/7/27 13:11
# @File    : s1.py

"""
select的使用
"""
import socket,select

#服务器的创建
server=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
server.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
server.bind(('',1022))
server.listen(5)
print 'start'
inputs=[server]
while 1:
    #select的原型为(rlist,wlist,xlist[,timeout]),
    # 其中rlist是等待读取的对象,
    # wlist是等待写入的对象,
    # xlist是等待异常的对象,
    rs,ws,es=select.select(inputs,[],[],1)
    for r in rs:
        if r is server:
            clientsock,clientaddr=r.accept()
            inputs.append(clientsock)
        else:
            data=r.recv(1024)
            if not data:
                inputs.remove(r)
            else:
                print data,'[]'

客户端:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2017/7/27 13:11
# @File    : c1.py


import socket
host='127.0.0.1'
port=1022
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect((host,port))
s.send('hello from client')
s.close()

总结一下,运行到这个语句时

rs,ws,es=select.select(inputs,[],[])

select函数阻塞程序运行,监控inputs中的套接字,当其中有套接字满足可读的条件(第一个参数为可读,如果是第二个参数则为可写),则把这个套接字返回给rs,然后程序继续运行。

至于套接字怎么才算可读呢?搜索可知,当套接字缓冲区大于1byte时,就被标记为可读。也就是说,当套接字收到客户端发来的数据,就变成可读,然后select就会把这个套接字取出来,进入下一步程序。