使用select实现非阻塞socket | dbafree首页
在linux,perl,python上都存在select系统调用。下面这两个python程序,可以用来学习和调试select操作。
参考至:http://blog.chinaunix.net/space.php?uid=199788&do=blog&id=99434
1.服务端代码
#!/home/oracle/dbapython/bin/python # -*- coding: utf-8 -*- """ 非阻塞socket的使用(此程序在ubuntu linux和windows xp上测试,Windows可以支持select.select) 监控socket的三个list:in/out/err 程序以5000ms的时间长度为间隔,如果有客户端的请求,接收连接并进行显示;如果没有的话, 每隔5000ms显示一次"no data coming" """ import socket,select host=""; port=50000; s = socket.socket(socket.AF_INET,socket.SOCK_STREAM) s.bind((host,port)); s.listen(5); while 1: infds,outfds,errfds = select.select([s,],[],[],0.1) # 如果infds状态改变,进行处理,否则不予理会 if len(infds) != 0: clientsock,clientaddr = s.accept() buf = clientsock.recv(8196) if len(buf) != 0: print (buf) clientsock.close() print "no data coming"2.客户端代码
#!/home/oracle/dbapython/bin/python # -*- coding: utf-8 -*- import socket,select host = "localhost" port = 50000 s = socket.socket(socket.AF_INET,socket.SOCK_STREAM) #请求连接时,会发送连接请求报文,此时select()会结束 #FD_ISSET(sockfd)当然大于零,因为有报文可读嘛! #然后server端进行accept s.connect((host,port)) #执行send,发送内容,server端accept接收到内容 ,进行打印 s.send("coming from select client by dbafree") s.close()为什么要用select来实现,因为accept是阻塞式的,执行一个accept会一直进行等待。
当然这种方式,说白了就是用select来监听连接的建立。在连接建立后,accept()函数会返回一个单独的客户端socket用于后续的通信,此时如果client端一直不发送数据,server端也会一直进行等待。
个人理解,欢迎指进。其它相关资料
man一下select
python doc上的解释:http://docs.python.org/library/select.html?highlight=select.select#select.select
linux上select:http://digdeeply.info/archives/10121463.html