io多路复用:可以监听多个文件描述符(socket对象)(文件句柄),一旦文件句柄出现变化,即可感知。

  1 sk1 = socket.socket()
2 sk1.bind(('127.0.0.1',8001))
3 sk1.listen()
4
5 # sk2 = socket.socket()
6 # sk2.bind(('127.0.0.1',8002))
7 # sk2.listen()
8 while True:
9 conn,address = sk.accept()#阻塞等待客户端连接、连接、客户端地址信息
10 print(conn,address)
11 conn.sendall(bytes('北京欢迎你',encoding='utf-8'))
12 while True:
13 ret_bytes = conn.recv(1024)
14 ret_str = str(ret_bytes,encoding='utf-8')
15 if ret_str == 'q':
16 break
17 conn.sendall(bytes(ret_str+'好',encoding='utf-8'))
18 print(address,conn)
19

sk1\sk2就叫作文件描述符、文件句柄。上面的程序只能执行sk1。

IO多路复用有一种机制,可以接受多个文件描述符,一旦有谁变化了,就处理。

  1 import socket
2 sk1 = socket.socket()
3 sk1.bind(('127.0.0.1',8001))
4 sk1.listen()
5
6 sk2 = socket.socket()
7 sk2.bind(('127.0.0.1',8002))
8 sk2.listen()
9
10 sk3 = socket.socket()
11 sk3.bind(('127.0.0.1',8002))
12 sk3.listen()
13
14 inputs = [sk1,sk2]
15 #本例是用select伪装成多处理用户连接请求,比socket的好处在于不用等待? 难点在于inputs里两类socket,客户端socket和服务端socket?
16 import select
17 while True:
18 #[sk1,sk2,],select内部自动监听sk1,sk2,sk3三个对象,一旦某个句柄发生变化,就会将其放到r_list里。第一次发生变化是sk.accept(),即有人来连sk1.则r_list = [sk1]
19 r_list,w_list,e_list = select.select(inputs,outputs,inputs,1)#等一秒看是否有人来连接,没有的话执行下一次循环。最多等待的时间。
20 print('正在监听的socket对象%d' % len(inputs))
21 print(r_list)
22 for sk1_or_conn in r_list:
23

IO多路复用是操作系统底层提供的功能,我们只是用Python去调用它,分三种方式,select,poll,epoll。windows只支持select.

select底层实现原理:

系统内部c语言进行for循环检测,当文件句柄发送变化的时候告诉我们。性能较低,并且只支持最多1024个文件描述符。

所以后来就有了poll,对于文件描述符个数没限制了,但底层也是用for循环实现的。

之后又出现了epoll,底层就不用for循环了,而是用异步实现的,把句柄都放进去,谁有变化了谁主动告诉epoll,而不是for循环一遍遍监测。所以epoll的性能是最高的。

Nginx的内部就是socket结合epoll来监听用户请求的。

for sk in e_list:  #e_list是发生错误的文件描述符列表

inputs.remove(sk)

  1 import socket
2 sk1 = socket.socket()
3 sk1.bind(('127.0.0.1',8001))
4 sk1.listen()
5
6 # sk2 = socket.socket()
7 # sk2.bind(('127.0.0.1',8002))
8 # sk2.listen()
9 #
10 # sk3 = socket.socket()
11 # sk3.bind(('127.0.0.1',8003))
12 # sk3.listen()
13 inputs = [sk1]
14 outputs = []
15 #本例是用select伪装成多处理用户连接请求,比socket的好处在于不用等待? 难点在于inputs里两类socket,客户端socket和服务端socket。
16 import select
17 while True:
18 #[sk1,sk2,],select内部自动监听sk1,sk2,sk3三个对象,一旦某个句柄发生变化
19 r_list,w_list,e_list = select.select(inputs,outputs,inputs,1)
20 print('正在监听的socket对象%d' % len(inputs))
21 print(r_list)
22 for sk1_or_conn in r_list:
23 #每一个连接对象
24 if sk1_or_conn == sk1:
25 #表示有新用户来连接
26 conn, address = sk1_or_conn.accept()
27 inputs.append(conn)
28 else:
29 #有老用户发消息了
30 try:
31 data_bytes = sk1_or_conn.recv(1024)
32 except Exception as ex:
33 #如果用户中断连接
34 inputs.remove(sk1_or_conn)
35 else:
36 #用户正常发消息
37 # data_str = str(data_bytes,encoding='utf-8')
38 # sk1_or_conn.sendall(bytes(data_str+'好',encoding = 'utf-8'))
39 outputs.append(sk1_or_conn)
40 #w_list仅仅存谁给我发过消息,如果想读写分离就会用到这个参数
41 for conn in w_list:
42 conn.sendall(bytes('hello',encoding='utf-8'))
43 outputs.remove(conn)
44

IO多路复用处理多用户请求

上面的难点在于要理解r_list其实并不等于inputs.

inputs里面两类数据,一类是服务端的socket sk1,另一类是客户端的socket(只要有人来连接就apend一个socket对象)

而r_list里面存的是发生变化的对象,多个用户来连sk1,r_list里就是sk1,而有用户发消息,那r_list里就变为发消息的socket对象其。

socketserver:
select/epoll + socket +多线程实现并发操作。

Python网络编程:IO多路复用的更多相关文章

  1. python 网络编程 IO多路复用之epoll

    python网络编程——IO多路复用之epoll 1.内核EPOLL模型讲解     此部分参考http://blog.csdn.net/mango_song/article/details/4264 ...

  2. python网络编程——IO多路复用之select

    1 IO多路复用的概念 原生socket客户端在与服务端建立连接时,即服务端调用accept方法时是阻塞的,同时服务端和客户端在收发数据(调用recv.send.sendall)时也是阻塞的.原生so ...

  3. python网络编程——IO多路复用之epoll

    1.内核EPOLL模型讲解     此部分参考http://blog.csdn.net/mango_song/article/details/42643971博文并整理 首先我们来定义流的概念,一个流 ...

  4. python网络编程——IO多路复用select/poll/epoll的使用

    转载博客: http://www.haiyun.me/archives/1056.html http://www.cnblogs.com/coser/archive/2012/01/06/231521 ...

  5. Python网络编程-IO阻塞与非阻塞及多路复用

    前言 问题:普通套接字实现的服务端的缺陷 一次只能服务一个客户端!                         accept阻塞! 在没有新的套接字来之前,不能处理已经建立连接的套接字的请求 re ...

  6. linux网络编程 IO多路复用 select epoll

    本文以我的小型聊天室为例,对于服务器端的代码,做了三次改进,我将分别介绍阻塞式IO,select,epoll . 一:阻塞式IO 对于聊天室这种程序,我们最容易想到的是在服务器端accept之后,然后 ...

  7. Socket网络编程-IO各种概念及多路复用

    Socket网络编程-IO各种概念及多路复用 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.操作系统相关知识 1>.同步和异步  函数或方法被调用的时候,调用者是否得到最 ...

  8. python网络编程基础(线程与进程、并行与并发、同步与异步、阻塞与非阻塞、CPU密集型与IO密集型)

    python网络编程基础(线程与进程.并行与并发.同步与异步.阻塞与非阻塞.CPU密集型与IO密集型) 目录 线程与进程 并行与并发 同步与异步 阻塞与非阻塞 CPU密集型与IO密集型 线程与进程 进 ...

  9. Python 网络编程(二)

    Python 网络编程 上一篇博客介绍了socket的基本概念以及实现了简单的TCP和UDP的客户端.服务器程序,本篇博客主要对socket编程进行更深入的讲解 一.简化版ssh实现 这是一个极其简单 ...

  10. python 网络编程要点

    From http://www.zhihu.com/question/19854853 Python网络编程是一个很大的范畴,个人感觉需要掌握的点有:1. 如何使用Python来创建socket, 如 ...

随机推荐

  1. mysql 批量修改字段方法

    一.正式环境操作注意事项: .关闭应用访问或者设置数据库只读 mysql设为只读方法: 开启只读: mysql> show global variables like "%read_o ...

  2. jupyter中添加conda环境

    安装完Anaconda利用conda创建了虚拟环境,但是启动jupyter notebook之后却找不到虚拟环境. 实际上是由于在虚拟环境下缺少kernel.json文件,解决方法如下: 首先安装ip ...

  3. Linux下RPM包的安装

    Linux下RPM包安装 二进制包(RPM包.系统默认包) RPM安装 rpm -ivh 包全名(查询依赖网址:http://www.rpmfind.net) -i(install):安装 -v(ve ...

  4. websocket python实现原理

    """ pip install ws4py """ import json from ws4py.client.threadedclient ...

  5. Oracle 批量修改某个用户下表的表空间

    说明:一般来说要修改表的表空间需要同时修改表的表空间和其对应的索引表空间,并且在修改含有BOLB字段的表的表空间时又不一样,具体请参考末尾的链接 思路:拼凑一个满足条件的批处理查询语句,将查询的结果复 ...

  6. React Native创建一个APP

    React Native 结合了 Web 应用和 Native 应用的优势,可以使用 JavaScript 来开发 iOS 和 Android 原生应用.在 JavaScript 中用 React 抽 ...

  7. 解决eth0网卡无法自动加载的问题

    问题:输入ifup eth0显示无法加载网卡所在的文件 解决办法: vi /etc/rc.d/rc.local 最后一行加入: ifup eth0 然后重启虚拟机即可解决问题. 本文为博主原创文章,未 ...

  8. Codeforces round 1106

    Div 2 536 题目链接 我还是太菜了.jpg E 傻逼DP直接做 我居然调了1.5h 我真的是太菜了.jpg 堆+扫描线直接维护每个位置的贪心结果 然后要么使用干扰 要么就接受贪心的结果 #in ...

  9. kettle学习笔记(三)——kettle资源库、运行方式与日志

    一.kettle资源库 资源库是用来保存转换任务的,用户通过图形界面创建的的转换任务可以保存在资源库中. 资源库可以使多用户共享转换任务,转换任务在资源库中是以文件夹形式分组管理的,用户可以自定义文件 ...

  10. 20155216 实验一 逆向与Bof基础

    实验一 逆向与Bof基础 一.直接修改程序机器指令,改变程序执行流程 使用 objdump -d pwn1 对pwn1文件进行反汇编. 可知main函数跳转至foo函数,先要使main函数跳转至get ...