在python中编写socket服务端模块(二):使用poll或epoll
在linux上编写socket服务端程序一般可以用select、poll、epoll三种方式,本文主要介绍使用poll和epoll编写socket服务端模块。
使用poll方式的服务器端程序代码:
import socket
import select
import Queue server_address=('10.0.2.15',21345)
server=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
server.setblocking(False)
server.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
server.bind(server_address)
server.listen(5) message_queues={}
#poll时间单位是毫秒
timeout = 1000 # Create a limit for the event
READ_ONLY = ( select.POLLIN | select.POLLPRI | select.POLLHUP | select.POLLERR)
READ_WRITE = (READ_ONLY|select.POLLOUT) # Set up the poller
poller = select.poll()
poller.register(server,READ_ONLY)
#Map file descriptors to socket objects
#server.fileno()是获得server这个socket的文件描述符,是int类型
fd_to_socket = {server.fileno():server,} while True: events = poller.poll(timeout)
#fd是描述符,flag是event状态,都是int类型
for fd ,flag in events:
# Retrieve the actual socket from its file descriptor
#s为当前的socket对象
s = fd_to_socket[fd] if flag & (select.POLLIN | select.POLLPRI) :
if s is server :
# A readable socket is ready to accept a connection
connection , client_address = s.accept()
print " Connection " , client_address
connection.setblocking(False) fd_to_socket[connection.fileno()] = connection
poller.register(connection,READ_ONLY) #Give the connection a queue to send data
message_queues[connection] = Queue.Queue()
else :
data = s.recv(1024)
if data:
# A readable client socket has data
print " received %s from %s " % (data, s.getpeername())
message_queues[s].put(data)
poller.modify(s,READ_WRITE)
else :
# Close the connection
print " closing" , s.getpeername()
# Stop listening for input on the connection
poller.unregister(s)
s.close()
del message_queues[s]
elif flag & select.POLLHUP :
#A client that "hang up" , to be closed.
print " Closing ", s.getpeername() ,"(HUP)"
poller.unregister(s)
s.close()
elif flag & select.POLLOUT :
#Socket is ready to send data , if there is any to send
try:
next_msg = message_queues[s].get_nowait()
except Queue.Empty:
# No messages waiting so stop checking
print s.getpeername() , " queue empty"
poller.modify(s,READ_ONLY)
else :
print " sending %s to %s" % (next_msg , s.getpeername())
s.send(next_msg)
elif flag & select.POLLERR:
#Any events with POLLERR cause the server to close the socket
print " exception on" , s.getpeername()
poller.unregister(s)
s.close()
del message_queues[s]
使用epoll方式的服务器端程序代码跟poll方式类似,具体代码如下:
import socket
import select
import Queue server_address=('10.0.2.15',21345)
server=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
server.setblocking(False)
server.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
server.bind(server_address)
server.listen(5) message_queues={}
#poll时间单位是毫秒
timeout = 1000 # Create a limit for the event
READ_ONLY = ( select.EPOLLIN | select.EPOLLPRI | select.EPOLLHUP | select.EPOLLERR)
READ_WRITE = (READ_ONLY|select.EPOLLOUT) # Set up the poller
epoller = select.epoll()
epoller.register(server,READ_ONLY)
#Map file descriptors to socket objects
#server.fileno()是获得server这个socket的文件描述符,是int类型
fd_to_socket = {server.fileno():server,} while True:
print "Waiting for the next event"
events = epoller.poll(timeout)
print events
#fd是描述符,flag是event状态
for fd ,flag in events:
# Retrieve the actual socket from its file descriptor
s = fd_to_socket[fd] if flag & (select.EPOLLIN | select.EPOLLPRI) :
if s is server :
# A readable socket is ready to accept a connection
connection , client_address = s.accept()
print " Connection " , client_address
connection.setblocking(False) fd_to_socket[connection.fileno()] = connection
epoller.register(connection,READ_ONLY) #Give the connection a queue to send data
message_queues[connection] = Queue.Queue()
else :
data = s.recv(1024)
if data:
# A readable client socket has data
print " received %s from %s " % (data, s.getpeername())
message_queues[s].put(data)
epoller.modify(s,READ_WRITE)
else :
# Close the connection
print " closing" , s.getpeername()
# Stop listening for input on the connection
epoller.unregister(s)
s.close()
del message_queues[s]
elif flag & select.EPOLLHUP :
#A client that "hang up" , to be closed.
print " Closing ", s.getpeername() ,"(HUP)"
epoller.unregister(s)
s.close()
elif flag & select.POLLOUT :
#Socket is ready to send data , if there is any to send
try:
next_msg = message_queues[s].get_nowait()
except Queue.Empty:
# No messages waiting so stop checking
print s.getpeername() , " queue empty"
epoller.modify(s,READ_ONLY)
else :
print " sending %s to %s" % (next_msg , s.getpeername())
s.send(next_msg)
elif flag & select.EPOLLERR:
#Any events with POLLERR cause the server to close the socket
print " exception on" , s.getpeername()
epoller.unregister(s)
s.close()
del message_queues[s]
客户端程序代码与上一篇博文中的相同。
在python中编写socket服务端模块(二):使用poll或epoll的更多相关文章
- python 并发编程 socket 服务端 客户端 阻塞io行为
阻塞io行为 server.accept server.recv client.send recv,accept 分为两个阶段 1.wait for data 对方把数据经过网络延迟送到自己的操作系 ...
- 关于调试php的socket服务端中遇到的问题及解决办法
今天终于把socket的服务端解决了,期间遇到了很多问题呢~ 1.用cmd运行php的问题: 2.socket_create()函数未定义问题: 3.查看端口的问题. 以下逐一说说解决办法: 1.在c ...
- 转:: 刺鸟:用python来开发webgame服务端(3)
来源:http://ciniao.me/article.php?id=11 --------------- 刺鸟原创文章,转载请注明出处 在之前的准备工作中,我们已经建立了一个socket服务器 ...
- Python中的socket网络模块
目录 Socket 服务端(server.py) 客户端(client.py) socket中的一些常用方法 Socket 对象(内建)方法 Python Internet 模块 Python3 提供 ...
- 转:: 刺鸟:用python来开发webgame服务端(1)
来源:http://ciniao.me/article.php?id=9 --------------- 刺鸟原创文章,转载请注明出处 在开始之前,先简单描述一下项目的特点:我要实现的是一个mm ...
- Django---Http协议简述和原理,HTTP请求码,HTTP请求格式和响应格式(重点),Django的安装与使用,Django项目的创建和运行(cmd和pycharm两种模式),Django的基础文件配置,Web框架的本质,服务器程序和应用程序(wsgiref服务端模块,jinja2模板渲染模块)的使用
Django---Http协议简述和原理,HTTP请求码,HTTP请求格式和响应格式(重点),Django的安装与使用,Django项目的创建和运行(cmd和pycharm两种模式),Django的基 ...
- socket服务端开发之测试使用threading和gevent框架
socket服务端开发之测试使用threading和gevent框架 话题是测试下多线程和gevent在socket服务端的小包表现能力,测试的方法不太严谨,也没有用event loop + pool ...
- AutoCAD.net支持后台线程-Socket服务端
最近因为公司项目的需求,CAD作为服务端在服务器中常驻运行,等待客户端远程发送执行任务的指令,最终确认用Socket-tcp通讯,CAD需要实时监听客户端发送的消息,这时就需要开启线程执行Socket ...
- 如何在Ruby中编写微服务?
[编者按]本文作者为 Pierpaolo Frasa,文章通过详细的案例,介绍了在Ruby中编写微服务时所需注意的方方面面.系国内 ITOM 管理平台 OneAPM 编译呈现. 最近,大家都认为应当采 ...
随机推荐
- 用C++编写程序,输出两个字符串的最大公共子字符串
#include<iostream> #include<string> using namespace std; int main() { string s_l,s_sh; ...
- Linux学习之scp命令
scp是secure copy的简写,用于在Linux下进行远程拷贝文件的命令,和它类似的命令有cp,不过cp只是在本机进行拷贝不能跨服务器,而且scp传输是加密的,可能会稍微影响一下速度.当你服务器 ...
- 监听enter事件
document.onkeydown=keyDownSearch; function keyDownSearch(e) { // 兼容FF和IE和Opera var theEvent = e || w ...
- Python进阶之自定义排序函数sorted()
sorted() .note-content {font-family: "Helvetica Neue",Arial,"Hiragino Sans GB",& ...
- 关于jQuery中toggle()函数的使用
今天遇到一个有趣的例子,将它记录下来. 一个一级菜单,里边有一个二级菜单,二级菜单是通过锚点来链接页面元素的.想要实现的效果是当点击锚点时,页面链接到相应锚点,同时二级菜单隐藏,再点击一级菜单时,继续 ...
- Facebook React Native 配置小结
2015 年 9 月 15 号,React Native for Android 发布.至此,React 基本完成了对多端的支持.基于 React / React Native 可以: H5, And ...
- Oracle系列:记录Record
Oracle系列:记录Record 分类: [Oracle] (15) 版权声明:本文为博主原创文章,未经博主允许不得转载. Oracle系列:记录(Record) 一,什么是记录(Record) ...
- 武汉新芯:定位存储器制造,两年后或推3D NAND
武汉新芯集成电路制造公司(XMC)2006成立,2012年底起独立经营,是国有制企业.为了区别于本土的制造巨头SMIC(中芯国际)和华力微电子(HLMC)等,XMC将立足存储器制造.近日,武汉新芯董事 ...
- 占成本85% SSD深度选购教你如何看颗粒
颗粒是固态硬盘负责容量和传输的介质,在这一方面上与优盘产品是相同的,从外观上看,颗粒占据了整个固态硬盘内部70%左右的空间,其同样做为成本技术,根据厂商的用料不同,成为了固态硬盘内部核心材料. 颗粒的 ...
- 关于“#ifdef __cplusplus”
CC++语言在编译的时候为了解决函数的多态问题,会将函数名和参数联合起来生成一个中间的函数名称,而C语言则不会,因此会造成链接时找不到对应函数的情况,此时C函数就需要用extern “C”进行链接指定 ...