多路复用(select、epoll)实现tcp服务
-------------------------------多路复用的服务器(select)-------------------------------
网络通信被Unix系统抽象为文件的读写,通常是一个设备,由设备驱动程序提供,驱动可以知道自身的数据是否可用。支持阻塞操作的设备驱动通常会实现一组自身的等待队列,如读/写等待队列用于支持上层(用户层)所需的block或non-block操作。设备的文件的资源如果可用(可读或者可写)则会通知进程,反之则会让进程睡眠,等到数据到来可用的时候,再唤醒进程。这些设备的文件描述符被放在一个数组中,然后select调用的时候遍历这个数组,如果对于的文件描述符可读则会返回改文件描述符。当遍历结束之后,如果仍然没有一个可用设备文件描述符,select让用户进程则会睡眠,直到等待资源可用的时候在唤醒,遍历之前那个监视的数组。每次遍历都是依次进行判断的。
缺点:
select的一个缺点在于单个进程能够监视的文件描述符的数量存在最大限制,在Linux上一般为1024,可以通过修改宏定义甚至重新编译内核的方式提升这一限制,但是这样也会造成效率的降低。一般来说这个数目和系统内存关系很大,具体数目可以cat /proc/sys/fs/file-max察看。32位机默认是1024个。64位机默认是2048.对socket进行扫描时是依次扫描的,即采用轮询的方法,效率较低。当套接字比较多的时候,每次select()都要通过遍历FD_SETSIZE个Socket来完成调度,不管哪个Socket是活跃的,都遍历一遍。这会浪费很多CPU时间。
应用:
#import select:对应import包的引用操作
#readable,writeable,exceptinal=select.select(inputs,[],[]):使用select对套接字组成的列表进行遍历,过滤出对应的未堵塞的套接字
python代码示例:
#coding=utf-8 #引用对应的包
from socket import * import select import sys #函数:main
def main():
#创建套接字
serTcpSocket=socket(AF_INET,SOCK_STREAM) #绑定端口和ip,sys.argv[1] 运行时传递的参数
serTcpSocket.bind(("",int(sys.argv[1]))) #打开被动监听
serTcpSocket.listen(5) print("-----服务器开启-----") #创建列表,存储对应的套接字
inputs=[serTcpSocket] #循环
while True:
#使用select进行对应套接字的处理过滤
readList,writeList,exceptList=select.select(inputs,[],[]) #遍历readList列表进行操作
for sockItem in readList:
#如果为服务器套接字,进行accept()数据的接收
if sockItem==serTcpSocket:
#监听接受客户端传递过来的数据信息
newSocket,destAddr=sockItem.accept() print("客户端(%s)以上线"%str(destAddr)) #将用于与客户端通信的套接字进行存储
inputs.append(newSocket) else:
#进行客户端发送过来的数据的接收
recvData=sockItem.recv(1024) #进行判断,如果传递过来的数据不为空
if len(recvData)>0:
#进行客户端发送过来的数据的打印操作
print("客户端(%s):%s"%(str(destAddr),recvData))
else:
#表示客户端下线
print("客户端(%s)以下线!"%str(destAddr)) #进行对应该客户端套接字的关闭操作
sockItem.close() #将该套接字从对应的列表中移除
inputs.remove(sockItem) #程序入口
if __name__=="__main__":
main()
select多路复用实现tcp服务
-------------------------------多路复用的服务器(epoll)-------------------------------
优点:
1、没有最大并发连接的限制,能打开的FD的上限远大于1024
2、效率提升,不是轮询的方式,不会随着FD数目的增加效率下降。只有活跃可用的FD才会调用callback函数;即epoll最大的优点就在于它只管你“活跃”的连接,而跟连接总数无关,因此在实际的网络环境中,epoll的效率就会远远高于select。
应用:
#import select:引用select包
#epoll=select.epoll():创建epoll对象
#soc.fileno():获取套接字对应的文件描述符
#epoll.register(soc.fileno(),select.EPOLLIN|select.EPOLLET):将创建的套接字添加到epoll的事件监听
EPOLLIN (可读)
EPOLLOUT (可写)
EPOLLET (ET模式)
epoll对文件描述符的操作有两种模式:LT(level trigger)和ET(edge trigger)。LT模式是默认模式,LT模式与ET模式的区别如下:
LT模式:当epoll检测到描述符事件发生并将此事件通知应用程序,应用程序可以不立即处理该事件。下次调用epoll时,会再次响应应用程序并通知此事件。
ET模式:当epoll检测到描述符事件发生并将此事件通知应用程序,应用程序必须立即处理该事件。如果不处理,下次调用epoll时,不会再次响应应用程序并通知此事件。
#epollList=epoll.poll():进行已注册套接字的扫描操作
#epoll.unregister(soc.fileno()):从epoll对象中注销该套接字
#coding=utf-8 #引用对应的包
from socket import * import select import sys #函数:main
def main():
#创建服务器的套接字
serTcpSocket=socket(AF_INET,SOCK_STREAM) #进行端口和ip的绑定操作
serTcpSocket.bind(("",int(sys.argv[1]))) #开启被动,进行监听
serTcpSocket.listen(10) #创建一个epoll对象
epoll=select.epoll() #使用epoll对套接字在操作系统中进行注册
epoll.register(serTcpSocket.fileno(),select.EPOLLIN|select.EPOLLET) #创建两个字典
#根据套接字的文件标识符对应套接字
connection={} #根据套接字的文件标识符对应ip和端口元组信息
address={} #提示服务开启
print("------服务开启-----") #进行循环遍历
while True:
#接收对象中,未阻塞的套接字
epollList = epoll.poll() for fd,event in epollList:
#判断是否为服务器的套接字
if fd==serTcpSocket.fileno():
#接收客户端传递过来的数据信息
newSocket,destAddr=serTcpSocket.accept() print("客户端(%s)以上线"%str(destAddr)) #将对应的数据向字典中进行存储
connection[newSocket.fileno()]=newSocket
address[newSocket.fileno()]=destAddr #将套接字在对应的epoll对象中进行注册
epoll.register(newSocket.fileno(),select.EPOLLIN|select.EPOLLET) elif event==select.EPOLLIN:
#在字典中取出对应的套接字对象和地址(ip和端口)
soc=connection[fd]
addr=address[fd] #接收客户端发送过来的数据信息
recvData=soc.recv(1024) #判断客户端是否下线
if len(recvData)>0:
#进行打印
print("客户端(%s):%s"%(str(addr),recvData)) #echo服务,将信息回发到客户端
soc.send(recvData)
else:
print("客户端(%s)以下线"%str(addr)) #进行该套接字在epoll中的注销操作
epoll.unregister(fd) #关闭该套接字
soc.close() #程序入口
if __name__=="__main__":
main()
多路复用epoll实现tcp服务
多路复用(select、epoll)实现tcp服务的更多相关文章
- linux网络编程 IO多路复用 select epoll
本文以我的小型聊天室为例,对于服务器端的代码,做了三次改进,我将分别介绍阻塞式IO,select,epoll . 一:阻塞式IO 对于聊天室这种程序,我们最容易想到的是在服务器端accept之后,然后 ...
- IO多路复用(二) -- select、poll、epoll实现TCP反射程序
接着上文IO多路复用(一)-- Select.Poll.Epoll,接下来将演示一个TCP回射程序,源代码来自于该博文https://www.cnblogs.com/Anker/p/3258674.h ...
- 利用select实现IO多路复用TCP服务端
一.相关函数 1. int select(int maxfdp, fd_set *readset, fd_set *writeset, fd_set *exceptset,struct timeva ...
- I/O模型系列之五:IO多路复用 select、poll、epoll
IO多路复用之select.poll.epoll IO多路复用:通过一种机制,一个进程可以监视多个描述符,一旦某个描述符就绪(一般是读就绪或者写就绪),能够通知程序进行相应的读写操作. 应用:适用于针 ...
- Linux 网络编程的5种IO模型:多路复用(select/poll/epoll)
Linux 网络编程的5种IO模型:多路复用(select/poll/epoll) 背景 我们在上一讲 Linux 网络编程的5种IO模型:阻塞IO与非阻塞IO中,对于其中的 阻塞/非阻塞IO 进行了 ...
- 网络编程socket 结合IO多路复用select; epool机制分别实现单线程并发TCP服务器
select版-TCP服务器 1. select 原理 在多路复用的模型中,比较常用的有select模型和epoll模型.这两个都是系统接口,由操作系统提供.当然,Python的select模块进行了 ...
- 04: 事件驱动、五种I/O操作、I/O多路复用select和epoll
网络编程其他篇 目录: 1.1 事件驱动 1.2 五种I/O操作 1.3 I/O 多路复用之select.poll.epoll详解 1.1 事件驱动返回顶部 1.什么是事件驱动 定义:就是根据不同事 ...
- I/O多路复用select/poll/epoll
前言 早期操作系统通常将进程中可创建的线程数限制在一个较低的阈值,大约几百个.因此, 操作系统会提供一些高效的方法来实现多路IO,例如Unix的select和poll.现代操作系统中,线程数已经得到了 ...
- 转一贴,今天实在写累了,也看累了--【Python异步非阻塞IO多路复用Select/Poll/Epoll使用】
下面这篇,原理理解了, 再结合 这一周来的心得体会,整个框架就差不多了... http://www.haiyun.me/archives/1056.html 有许多封装好的异步非阻塞IO多路复用框架, ...
随机推荐
- HDFS笔记——技术点汇总
目录 · 概况 · 原理 · HDFS 架构 · 块 · NameNode · SecondaryNameNode · fsimage与edits合并 · DataNode · 数据读写 · 容错机制 ...
- ServletContext对象统计在线人数
package com.zdsofe.servlet1; import java.io.IOException; import java.io.PrintWriter; import javax.se ...
- WAS 部署 Birt 报表出现 error.CannotStartupOSGIPlatform 和 更新web.xml
在WAS7.0中部署Birt报表会出现error.CannotStartupOSGIPlatform错误,通常需要这样修改 1.依次打开Applications->WebSphere enter ...
- Nlpir Parser灵玖文本语义挖掘系统数据采集
在计算机广泛应用的今天,数据采集的重要性是十分显著的.它是计算机与外部物理世界连接的桥梁.各种类型信号采集的难易程度差别很大. 灵玖软件Nlpir Parser文本语义挖掘系统以分词技术为基础,集成了 ...
- 教你上传本地代码到github
最近想起学Git,并且注册了Github. 将新创建的本地代码上传到github上,这里简单的记录一下,我喜欢使用命令行,这里全用命令行来实现,不了解Git命令的可以去了解下. 第一步:建立git仓库 ...
- sql必知必会-总结篇
总结: 1.全书总览:数据查询.新增.删除:表的新增.更新操作:视图.存储过程.事务.索引的描述,高级sql功能:约束.触发器.索引 2.特色:术语简明定义,讲述最简单化.简而全面. 3.长进的地方: ...
- [AOP系列]Autofac+Castle实现AOP日志
一.前言 最近公司新项目,需要搭架构进行开发,其中需要对一些日志进行输出,经过一番查找,发现很多博文都是通过Spring.Net.Unity.PostSharp.Castle Windsor这些方式实 ...
- POJ-1182 食物链(并查集)
食物链 Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 75814 Accepted: 22528 Description ...
- ChromeDriver,IEDriver,Firefox配置
ChromeDriver: 下载ChromeDriver.exe,放入某个文件夹,如C:\Program Files (x86)\Google\Chrome\Application,把此路径加入pat ...
- python进阶(6):多态,封装
昨天说了面向对象三大特性的继承,今天来说多态和封装,很多其他程序员说python不支持多态没有多态,并不是python没有多态,而是python处处皆多态.今天的讲课重点会放在封装. 一.多态 1.多 ...