通常情况下,socket上的I/O会阻塞。即除非操作结束,否则程序不会照常进行。而以下集中情况需要在非阻塞模式下进行:
1. 网络接口在等待数据时是活动的,可以做出相应;
2. 在不使用线程或进程的情况下也可以同时处理多个网络相关任务;
3. 在网络上等待的时候可以执行其它计算
在以上情况中,可以使用两个标准工具解决,poll和select。它们都可以通知操作系统哪个socket对程序感兴趣,当该socket上有事件发生时,操作系统才调用处理程序。
服务器程序每隔5秒向连接对象发送系统当前时间,如下:

#! /usr/bin/env python
# Delaying Server - Chapter 5 - delayserver.py import socket, traceback, time host = '' # Bind to all interface
port = 51423 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((host, port))
s.listen(1) while 1:
try:
clientsock, clientaddr = s.accept()
except KeyboardInterrupt:
raise
except:
traceback.print_exc()
continue # Process the connection
try:
print "Got Connection from ", clientsock.getpeername()
while 1:
try:
clientsock.sendall(time.asctime() + "\n")
except:
break
time.sleep(5)
except (KeyboardInterrupt, SystemExit):
raise
except:
traceback.print_exc() # Close the connection try:
clientsock.close()
except KeyboardInterrupt:
raise
except:
traceback.print_exc()

poll客户端程序如下:

#! /usr/bin/env python
# Nonblocking I/O - Chapter 5- pollclient.py import socket, sys, select host = "localhost"
port = 51423 spinsize = 10
spinpos = 0
spindir = 1 def spin():
global spinsize, spinpos, spindir
spinstr = '.'*spinpos + '|' + '.'*(spinsize-spinpos-1)
sys.stdout.write('\r'+spinstr+' ')
sys.stdout.flush() spinpos += spindir
if spinpos < 0:
spindir = 1
spinpos = 1
elif spinpos >= spinsize:
spinpos -= 2
spindir = -1 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.connect((host, port)) p = select.poll()
p.register(s.fileno(), select.POLLIN | select.POLLERR | select.POLLHUP)
while 1:
results = p.poll(50)
if len(results):
if results[0][1] == select.POLLIN:
data = s.recv(4096)
if not len(data):
print "\rRemote en closed connection; exiting."
break
# Only one item in here -- if there's anything, it's for me
sys.stdout.write("\rReceived: "+data)
sys.stdout.flush()
else:
print "\rProblem occured; exiting."
sys.exit(0)
spin()

等价的,select客户端如下:

#! /usr/bin/env python
# Nonblocking I/O with select() - Chapter 5 - selectclient.py import socket, sys, select host = 'localhost'
port = 51423 spinsize = 10
spinpos = 0
spindir = -1 def spin():
global spinsize, spinpos, spindir
spinstr = '.'*spinpos + '|' + '.'*(spinsize-spinpos-1)
sys.stdout.write('\r'+spinstr+' ')
sys.stdout.flush() spinpos += spindir
if spinpos < 0:
spinpos = 1
spindir = 1
elif spinpos >= spinsize:
spinpos -= 2
spindir = -1 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.connect((host, port)) while 1:
infds, outfds, errfds = select.select([s], [], [s], 0.05) # [s] just the same as[s.fileno()], only need to be a list.
if len(infds):
# Normally, one would use something like "for fd in infds" here.
# We don't bother since there will only ever be a single file
# descriptor here.
data = s.recv(4096)
if not len(data):
print "\rRemote and closed connection; exiting."
break
# Only one item in here -- if there's anything, it's for us.
sys.stdout.write("\rReceived: "+data)
sys.stdout.flush
if len(errfds):
print "\rProblem occurred; exiting."
sys.exit(0)
spin()

运行截图如下:

【Pyhton Network】使用poll()或select()实现非阻塞传输的更多相关文章

  1. 用select实际非阻塞I/O

    非阻塞read/write 函数返回0表示可读或可写, -1表示select失败或超时 select返回0表示超时,-1表示读取失败,1表示可读或可写 int read_timeout(int fd, ...

  2. 非阻塞socket调用connect, epoll和select检查连接情况示例

    转自http://www.cnblogs.com/yuxingfirst/archive/2013/03/08/2950281.html 我们知道,linux下socket编程有常见的几个系统调用: ...

  3. (转)非阻塞Connect对于select时应注意问题

    对于面向连接的socket类型(SOCK_STREAM,SOCK_SEQPACKET)在读写数据之前必须建立连接,首先服务器端socket必须在一个客户端知道的地址进行监听,也就是创建socket之后 ...

  4. 网络IO模型:同步IO和异步IO,阻塞IO和非阻塞IO

    同步(synchronous) IO和异步(asynchronous) IO,阻塞(blocking) IO和非阻塞(non-blocking)IO分别是什么,到底有什么区别?这个问题其实不同的人给出 ...

  5. 转 网络IO模型:同步IO和异步IO,阻塞IO和非阻塞IO

    此文章为转载,如有侵权,请联系本人.转载出处,http://blog.chinaunix.net/uid-28458801-id-4464639.html 同步(synchronous) IO和异步( ...

  6. 阻塞IO、非阻塞IO的区别

    1.类与类之间的关系:依赖,实现,泛化(继承),关联,组合,聚合. 1)依赖(虚线):一个类是 另一个类的函数参数 或者 函数返回值. 2)实现(实线加小圆):对纯虚函数类(抽象类)的实现. 3)继承 ...

  7. 同步IO,异步IO,阻塞IO,非阻塞IO

    同步(synchronous):一个进程在执行某个任务时,另外一个进程必须等待其执行完毕,才能继续执行 #所谓同步,就是在发出一个功能调用时,在没有得到结果之前,该调用就不会返回.按照这个定义, 其实 ...

  8. socket编程 —— 非阻塞socket (转)---例子已上传至文件中

    在上一篇文章 <socket编程——一个简单的例子> http://blog.csdn.net/wind19/archive/2011/01/21/6156339.aspx 中写了一个简单 ...

  9. TCP非阻塞accept和非阻塞connect

    http://blog.chinaunix.net/uid-20751538-id-238260.html 非阻塞accept     当一个已完成的连接准备好被accept的时候,select会把监 ...

随机推荐

  1. 利用微软类库 Visual Studio International Pack 汉字转拼音

    首先,从微软官网下载安装包:http://www.microsoft.com/downloads/zh-cn/details.aspx?FamilyID=44CAC7F0-633B-477D-AED2 ...

  2. (八)Hibernate 映射关系

    所有项目导入对应的hibernate的jar包.mysql的jar包和添加每次都需要用到的HibernateUtil.java 第一节:Hibernate 一对一映射关系实现 1,按照主键映射: 2, ...

  3. python 随机生成用户名、密码、手机号码

    #!C:\Python #!/usr/bin/env python #-*- coding:utf-8 -*- import string import random minlength = 6 ma ...

  4. java File详解

    一.简介 File类是“文件”和“目录名”的抽象表示形式.因此在java语言中,File类既可以表示文件也可以表示目录. 尽管java.io定义的大多数类是实行流式操作的,而File类则不是,它没有指 ...

  5. free -m

    free -m total used free shared buffers cached Mem: 7760 1572   6187          0              9       ...

  6. Mysql表操作

    查看表结构: 可以使用describe或show create table语句查看表的结构: describe表名; Show create table 表名; 修改表名: Alter table 旧 ...

  7. Chocolatey:Windows软件包管理器

    Chocolatey 2016-08-03 https://chocolatey.org/ Chocolatey是一个Windows软件包管理器,就像Nuget或者npm,或者说类似Linux上的ap ...

  8. centos不能挂在ntfs

    root@s 下载]# mount /dev/sdb1 /mnt mount: unknown filesystem type 'ntfs' wget http://www.tuxera.com/co ...

  9. 一步步学习ASP.NET MVC3 (15)——过滤器

    请注明转载地址:http://www.cnblogs.com/arhat 今天老魏和大家一起讨论一下ASP.NET MVC中非常重要的一个知识:"过滤器".那么这个"过滤 ...

  10. CLLocationManager 位置定位

    第一步,新建一个singleView的空白工程,如果新建,这里不做赘述了. 第二步:因为地图开发相关的framework:MapKit.framework.CoreLocation.framework ...