-------------------------------多路复用的服务器(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服务的更多相关文章

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

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

  2. IO多路复用(二) -- select、poll、epoll实现TCP反射程序

    接着上文IO多路复用(一)-- Select.Poll.Epoll,接下来将演示一个TCP回射程序,源代码来自于该博文https://www.cnblogs.com/Anker/p/3258674.h ...

  3. 利用select实现IO多路复用TCP服务端

    一.相关函数 1.  int select(int maxfdp, fd_set *readset, fd_set *writeset, fd_set *exceptset,struct timeva ...

  4. I/O模型系列之五:IO多路复用 select、poll、epoll

    IO多路复用之select.poll.epoll IO多路复用:通过一种机制,一个进程可以监视多个描述符,一旦某个描述符就绪(一般是读就绪或者写就绪),能够通知程序进行相应的读写操作. 应用:适用于针 ...

  5. Linux 网络编程的5种IO模型:多路复用(select/poll/epoll)

    Linux 网络编程的5种IO模型:多路复用(select/poll/epoll) 背景 我们在上一讲 Linux 网络编程的5种IO模型:阻塞IO与非阻塞IO中,对于其中的 阻塞/非阻塞IO 进行了 ...

  6. 网络编程socket 结合IO多路复用select; epool机制分别实现单线程并发TCP服务器

    select版-TCP服务器 1. select 原理 在多路复用的模型中,比较常用的有select模型和epoll模型.这两个都是系统接口,由操作系统提供.当然,Python的select模块进行了 ...

  7. 04: 事件驱动、五种I/O操作、I/O多路复用select和epoll

    网络编程其他篇 目录: 1.1 事件驱动 1.2 五种I/O操作 1.3 I/O 多路复用之select.poll.epoll详解 1.1 事件驱动返回顶部 1.什么是事件驱动  定义:就是根据不同事 ...

  8. I/O多路复用select/poll/epoll

    前言 早期操作系统通常将进程中可创建的线程数限制在一个较低的阈值,大约几百个.因此, 操作系统会提供一些高效的方法来实现多路IO,例如Unix的select和poll.现代操作系统中,线程数已经得到了 ...

  9. 转一贴,今天实在写累了,也看累了--【Python异步非阻塞IO多路复用Select/Poll/Epoll使用】

    下面这篇,原理理解了, 再结合 这一周来的心得体会,整个框架就差不多了... http://www.haiyun.me/archives/1056.html 有许多封装好的异步非阻塞IO多路复用框架, ...

随机推荐

  1. 读书笔记_MVC__关于通过js构建ORM,实现Model层

    最近一直在学习MVC构建富应用的WEB程序,自己一直对MVC的设计模式理解的不是十分透彻,终于在研读了github上Spine的源码之后,对构建Model层有了一点自己的理解. 本文仅为个人理解,如有 ...

  2. 【html】 a 标签

    摘要 嗷呜,发现好多前端细节,基础不扎实啊,喵了个咪 target 属性 在制定框架中打开 <a href="a.html" target="view_frame& ...

  3. hive配置过程中出现的一个问题

    执行hive里面的insert语句的时候,报错,执行失败查看hadoop的日志文件之后发现错误的详细信息如下: 把hdfs-site.xml中的hadoop.tmp.dir这个属性添加到core-si ...

  4. Kotlin + Spring Boot 请求参数验证

    编写 Web 应用程序的时候,经常要做的事就是要对前端传回的数据进行简单的验证,比如是否非空.字符长度是否满足要求,邮箱格式是否正确等等.在 Spring Boot 中,可以使用 Bean Valid ...

  5. 实例甜点 Unreal Engine 4迷你教程(1)之如何用C++将纹理绘制在UserWidget的Image小部件上

    完成本迷你教程之前,请前往完成以下迷你教程: 无前置教程待完成. 本教程适合的人群: 初学者,具有开发经验两周: 本示例的目的:为了在代码中实现UMG中的这个功能: 说明:这是一些列迷你教程的首篇,所 ...

  6. Python网络数据采集2-wikipedia

    Python网络数据采集2-wikipedia 随机链接跳转 获取维基百科的词条超链接,并随机跳转.可能侧边栏和低栏会有其他链接.这不是我们想要的,所以定位到正文.正文在id为bodyContent的 ...

  7. 45. leetcode 504. Base 7

    504. Base 7 Given an integer, return its base 7 string representation. Example 1: Input: 100 Output: ...

  8. 分布式事务,EventBus 解决方案:CAP【中文文档】

    前言 很多同学想对CAP的机制以及用法等想有一个详细的了解,所以花了将近两周时间写了这份中文的CAP文档,对 CAP 还不知道的同学可以先看一下这篇文章. 本文档为 CAP 文献(Wiki),本文献同 ...

  9. rocketmq client for c#

    基于ikvm的rocketmq的c#客户端,由于阿里对c#不敏感,对这方面的东西缺少.因为工作需要弄了一个,分享给大家 https://github.com/franknew/RocketMQ-Cli ...

  10. Spring 实现自定义 bean 的扩展

    Spring mvc 提供了扩展 xml 的机制,用来编写自定义的 xml bean ,例如 dubbo 框架,就利用这个机制实现了好多的 dubbo bean,比如 <dubbo:applic ...