在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 编译呈现. 最近,大家都认为应当采 ...
随机推荐
- google base库中的WaitableEvent
这个类说白了就是对windows event的封装,没有什么特别的,常规做法,等侍另一线程无非就是等侍事件置信waitsingleobject,通知事件无非就是setevent,一看就明白,不就详解, ...
- MySQL:ERROR 1217 (23000): Cannot delete or update a parent row: a foreign key constraint fails
MySQL在删除一张表时出现 ERROR 1217 (23000): Cannot delete or update a parent row: a foreign key constraint fa ...
- 比callback更简洁的链式执行promise
promise自己理解的也不够深刻,具体知识点不在这里细说了 直接上个例子,清晰明了,自己去悟吧 <script type="text/javascript"> //模 ...
- 解决ie6里png图片透明变白色bug
加入这段js就行了. function correctPNG() // correctly handle PNG transparency in Win IE 5.5 & 6. { var a ...
- OpenCV学习 3:平滑过度与边缘检测
原创文章,欢迎转载,转载请注明出处 用来记录学习的过程,这个是简单的相关函数的熟悉,内部机制和选择何种选择函数参数才能达到自己的要求还不太清楚,先学者吧..后面会慢慢清楚的. 和前面相比,主 ...
- getchar()与EOF
大师级经典的著作,要字斟句酌的去读,去理解.以前在看K&R的The C Programming Language(Second Edition)中第1.5节的字符输入/输出,很迷惑getcha ...
- MiniSD卡是什么
Mini SD卡比目前主流的普通SD卡(如DC或DV上使用的SD卡),在外形上更加小巧,重量仅有3克左右,体积只有21.5x20x1.4mm,比普通SD卡足足节省了60%的空间.别小看这么小的外形,它 ...
- 编译时出现clock skew detected, your build may be incompeleted
错误原因为文件修改时间大于系统时间,这时候如果date输出系统时间,会发现这个时间是错误的.在nachos实习时多次出现这个错误,简单的方法尝试make多次直到有一次出现'nachos' is up ...
- java中关于线程间协作所用关键字synchronized,wait,notify的用法
wait/notify()关键字适用于一个线程通知另一个线程所需的条件状态已就绪,最常用于线程在循环中休眠直到获取特定条件的场景. 例如,一个线程一直等待直到队列中有一个组件能够处理:当组件添加到队列 ...
- Xposed出现 java.lang.IllegalAccessError: Class ref in pre-verified class resolved to unexpected implementation
Xposed出现 java.lang.IllegalAccessError: Class ref in pre-verified class resolved to unexpected implem ...