Python: 使用select函数编写nonblocking TCP/IP socket程序
来源:互联网 发布:mysql as省略 编辑:程序博客网 时间:2024/05/23 15:40
select函数的理解对于灵活运用socket函数编程有直接的影响,我们编写的网络库一般需要支持多连接,因此select提供的特性很好的满足了这一需求。关于select的解释可以参考:select(2)
使用C或者C++编写一个实例程序相对比较麻烦,我们可以直接使用Python快速开发一个 nonblocking TCP/IP socket Demo来看一下select怎么应用到Socket网络编程。先说明在Python中的socket模块和select模块中提供的函数和 Linux Programmer's Manual中的定义基本相同,用法完全可以借鉴。
在Linux中,我们可以使用select函数实现I/O端口的复用,传递给 select函数的参数会告诉内核:
•我们所关心的文件描述符
•对每个描述符,我们所关心的状态。(我们是要想从一个文件描述符中读或者写,还是关注一个描述符中是否出现异常)
•我们要等待多长时间。(我们可以等待无限长的时间,等待固定的一段时间,或者根本就不等待)
从 select函数返回后,内核告诉我们一下信息:
•对我们的要求已经做好准备的描述符的个数
•对于三种条件哪些描述符已经做好准备.(读,写,异常)
先看Echo Server的代码:
# echo server example
import select
import socket
import sys
import Queue
# Create a TCP/IP socket
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.setblocking(0)
# Bind the socket to the port
server_address = ('localhost', 10000)
print >>sys.stderr, 'starting up on %s port %s' % server_address
server.bind(server_address)
# Listen for incoming connections
server.listen(5)
# Sockets from which we expect to read
inputs = [ server ]
# Sockets to which we expect to write
outputs = [ ]
# Outgoing message queues (socket:Queue)
message_queues = {}
while inputs:
# Wait for at least one of the sockets to be ready for processing
print >>sys.stderr, 'waiting for the next event'
readable, writable, exceptional = select.select(inputs, outputs, inputs)
# Handle inputs
for s in readable:
if s is server:
# A "readable" socket is ready to accept a connection
connection, client_address = s.accept()
print >>sys.stderr, ' connection from', client_address
connection.setblocking(0)
inputs.append(connection)
# Give the connection a queue for data we want to send
message_queues[connection] = Queue.Queue()
else:
data = s.recv(1024)
if data:
# A readable client socket has data
print >>sys.stderr, ' received "%s" from %s' % (data, s.getpeername())
message_queues[s].put(data)
# Add output channel for response
if s not in outputs:
outputs.append(s)
else:
# Interpret empty result as closed connection
print >>sys.stderr, ' closing', client_address
# Stop listening for input on the connection
if s in outputs:
outputs.remove(s)
inputs.remove(s)
s.close()
# Remove message queue
del message_queues[s]
# Handle outputs
for s in writable:
try:
next_msg = message_queues[s].get_nowait()
except Queue.Empty:
# No messages waiting so stop checking for writability.
print >>sys.stderr, ' ', s.getpeername(), 'queue empty'
outputs.remove(s)
else:
print >>sys.stderr, ' sending "%s" to %s' % (next_msg, s.getpeername())
s.send(next_msg)
# Handle "exceptional conditions"
for s in exceptional:
print >>sys.stderr, 'exception condition on', s.getpeername()
# Stop listening for input on the connection
inputs.remove(s)
if s in outputs:
outputs.remove(s)
s.close()
# Remove message queue
del message_queues[s]
先看Echo Client的代码如下:
#Client Process
import socket
import sys
messages = [ 'This is the message. ', 'It will be sent ', 'in parts.']
server_address = ('localhost', 10000)
# Create a TCP/IP socket
socks = [ socket.socket(socket.AF_INET, socket.SOCK_STREAM),
socket.socket(socket.AF_INET, socket.SOCK_STREAM),
]
# Connect the socket to the port where the server is listening
print >>sys.stderr, 'connecting to %s port %s' % server_address
for s in socks:
s.connect(server_address)
for message in messages:
# Send messages on both sockets
for s in socks:
print >>sys.stderr, '%s: sending "%s"' % (s.getsockname(), message)
s.send(message)
# Read responses on both sockets
for s in socks:
data = s.recv(1024)
print >>sys.stderr, '%s: received "%s"' % (s.getsockname(), data)
if not data:
print >>sys.stderr, 'closing socket', s.getsockname()
s.close()
下面是运行结果:
先开启Echo Server
再启动Client
紧接着观察Server端的打印信息
最后需要提的一点是select是跨平台的,因此这里的例子是在Windows上运行的,而类似功能的poll(2)和epoll(7)都是只能运行在Linux平台上。
参考资料:
1. select(2)
2. http://blog.csdn.net/lingfengtengfei/article/details/12392449
3.《The.Python.Standard.Library》
0 0
- Python: 使用select函数编写nonblocking TCP/IP socket程序
- Tcp socket程序编写
- epoll ET mode with tcp nonblocking socket
- socket——tcp-nonblocking-server-client
- php编写socket服务TCP/IP
- TCP/IP编程之select函数详解
- Python网络通信之socket模块(四)基于Tcp/Ip的TCP交互通信serve/client的编写过程
- 编写用TCP/IP的通讯程序
- socket中的select函数使用
- socket中的select函数使用
- Windows Socket select函数使用
- TCP/IP编程之socket函数详解
- 在python中编写socket服务端模块(一):使用select
- 在python中编写socket服务端模块(一):使用select
- 深入研究socket编程(3)——使用select函数编写客户端和服务器
- nagios当中使用nonblocking方式建立tcp连接
- Socket使用TCP/IP如何实现通信
- 使用c++TCP /IP 编程 ,socket
- ASP.NET Razor - C# 变量
- 学习笔记 Java概述 2014.7.8
- 力不从心
- CAShapeLayer
- android-----JNI学习 helloworld
- Python: 使用select函数编写nonblocking TCP/IP socket程序
- cocos2d-x,Eclipse搭建Android环境
- Android做了些什么?
- WINCE开发相关知识整理
- Sqlite 反射机制封装数据库
- 设置或获取某一个节点里所包含的HTML
- MIGRATE OPENSTACK KEYSTONE TO A DIFFERENT IP ADDRESS
- JavaScript 学习心得(一)
- Xcode5提交代码到github