通常情况下,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. 40个Java集合面试问题和答案【中】【转载】

    接上文:http://www.cnblogs.com/xujianbo/p/5148075.html   16.UnsupportedOperationException是什么? Unsupporte ...

  2. 快速登录IRC网络聊天室

    随便起个NickName,进行人机验证,然后点击Connect进去就可以咯.

  3. C# 并行开发总结

    本文内容 均参考自 <C#并行高级编程> TPL 支持 数据并行(有大量数据要处理,必须对每个数据执行同样的操作, 任务并行(有好多可以并发运行的操作),流水线(任务并行和数据并行的结合体 ...

  4. LIS

    五:LIS 概念 最长上升子序列(Longest Increasing Subsequence,LIS),在计算机科学上是指一个序列中最长的单调递增的子序列.比如一个序列31 2 6 3 8,他的最长 ...

  5. Java抽奖小程序

    package com.test; import java.awt.Color; import java.awt.Font; import java.awt.event.ActionEvent; im ...

  6. ThreadPoolExecutor 线程池的实现

    ThreadPoolExecutor继承自 AbstractExecutorService.AbstractExecutorService实现了 ExecutorService 接口. 顾名思义,线程 ...

  7. mysql 1045的的解决方案

    找到配置文件my.ini  ,然后将其打开,可以选择用记事本打开 打开后,搜索mysqld关键字 找到后,在mysqld下面添加skip-grant-tables,保存退出. 然后重启mysql服务 ...

  8. JavaScript 作用域和作用域链

    作用域是JavaScript最重要的概念之一,想要学好JavaScript就需要理解JavaScript作用域和作用域链的工作原理.今天这篇文章对JavaScript作用域和作用域链作简单的介绍,希望 ...

  9. 替换a链接的href和title

    新项目准备验收,客户检测网页有安全隐患,说是当前网页使用“http://”有风险,指定外部链接不用“http://”怎么整…… 后来想到用JS替换字符串去操作,找了半天总算找到合用的,最终是用JQ去更 ...

  10. Java小例子——穷举质数,求平方和,求质因子。

    求平方和 public static void main(String[] args) throws IOException { int n; String s; BufferedReader buf ...