一. 简介

  socketserver在内部是由I/O多路复用,多线程和多进程,实现了并发通信。IO多路复用的系统消耗很小。

IO多路复用底层就是监听socket对象内部是否有变化,是否在收发消息,Python中select模块提供了select poll epoll 三种方式来实现IO多路复用,支持不同的操作系统。

  windows : 提供select

  Mac : 提供select

  Linux : 提供select, poll, epoll

(1)select简介:

  select 默认会将每一个变化的socket加入一个他自己维护的列表中,但是并不会明确是哪一个socket,它内部其实是通过一个for循环遍历整个列表,当列表中的socket很多的时候,for循环就会浪费资源。select默认可以监听1024个链接,它是由linux在同文件中定义的,可修改。select不是安全的线程,如果你把一个socket加入到select中,突然另外一个线程关闭了这个socket,那么接下来select的行为是随机的。

(2)poll简介:

  poll修复了select的一些问题,例如去掉了1024个链接限制,想要监听多少都可以,poll不在修改传入的数组,但是poll依然不是线程安全的。

(3)epoll简介:

  epoll不仅会告诉你socket组里面的数据,还会告诉你具体哪个socket有数据,无需自己寻找。而且epoll终于是线程安全的了。然而epoll局限于

Linux操作系统。

二 . 应用

select 方法

句柄列表11, 句柄列表22, 句柄列表33 = select.select(句柄序列1, 句柄序列2, 句柄序列3, 超时时间)<br>
参数: 可接受四个参数(前三个必须)
返回值:三个列表
  
select方法用来监视文件句柄,如果句柄发生变化,则获取该句柄。
1、当 参数1 序列中的句柄发生可读时(accetp和read),则获取发生变化的句柄并添加到 返回值1 序列中
2、当 参数2 序列中含有句柄时,则将该序列中所有的句柄添加到 返回值2 序列中
3、当 参数3 序列中的句柄发生错误时,则将该发生错误的句柄添加到 返回值3 序列中
4、当 超时时间 未设置,则select会一直阻塞,直到监听的句柄发生变化
   当 超时时间 = 1时,那么如果监听的句柄均无任何变化,则select会阻塞 1 秒,之后返回三个空列表,如果监听的句柄有变化,则直接执行。

 

(1)监听客户端连接

import socket
import select

sk = socket.socket()
sk.bind(("127.0.0.1", 9999,))
sk.listen(5)

while True:
    rlist, w, e = select.select([sk, ], [], [], 5)
    # 监听sk(服务器端)对象,如果sk对象发生变化,表示有客户端来连接了,此时rlist值为[sk]
    # 监听conn对象,如果conn发生变化,表示客户端有消息发送过来了,此时rlist的值为[客户端]
    print(rlist)

    for r in rlist:
        print(r)
        conn, address = r.accept()
        conn.sendall(bytes("hello", encoding="utf-8"))
服务端

相关文章:

  • 2021-11-16
猜你喜欢
  • 2021-12-14
  • 2021-07-22
  • 2021-05-04
  • 2022-02-20
  • 2022-12-23
  • 2021-10-03
  • 2021-10-06
相关资源
相似解决方案