在无数据的无阻塞套接字的情况下,recv将抛出socket.error异常,并且异常的值将具有EAGAIN或EWOULDBLOCK的错误号。例:
import sysimport socketimport fcntl, osimport errnofrom time import sleeps = socket.socket(socket.AF_INET, socket.SOCK_STREAM)s.connect(('127.0.0.1',9999))fcntl.fcntl(s, fcntl.F_SETFL, os.O_NONBLOCK)while True: try: msg = s.recv(4096) except socket.error, e: err = e.args[0] if err == errno.EAGAIN or err == errno.EWOULDBLOCK: sleep(1) print 'No data available' continue else: # a "real" error occurred print e sys.exit(1) else: # got a message, do something :)
在您通过
socket.settimeout(n)或通过超时启用了非阻塞行为的情况下,情况有所不同
socket.setblocking(False)。在这种情况下,仍会引发socket.error,但在超时的情况下,异常的伴随值始终是设置为“超时”的字符串。因此,要处理这种情况,您可以执行以下 *** 作:
import sysimport socketfrom time import sleeps = socket.socket(socket.AF_INET, socket.SOCK_STREAM)s.connect(('127.0.0.1',9999))s.settimeout(2)while True: try: msg = s.recv(4096) except socket.timeout, e: err = e.args[0] # this next if/else is a bit redundant, but illustrates how the # timeout exception is setup if err == 'timed out': sleep(1) print 'recv timed out, retry later' continue else: print e sys.exit(1) except socket.error, e: # Something else happened, handle error, exit, etc. print e sys.exit(1) else: if len(msg) == 0: print 'orderly shutdown on server end' sys.exit(0) else: # got a message do something :)
如评论中所述,这也是一种更可移植的解决方案,因为它不依赖于 *** 作系统特定的功能来将套接字置于非阻塞模式。
有关更多详细信息,请参见recv(2)和python
socket。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)