您好, 欢迎来到 !    登录 | 注册 | | 设为首页 | 收藏本站

如果在超时之前没有收到任何数据,Python的socket.recv()对于非阻塞套接字返回什么?

如果在超时之前没有收到任何数据,Python的socket.recv()对于非阻塞套接字返回什么?

在无数据的无阻塞套接字的情况下,recv将抛出socket.error异常,并且异常的值将具有EAGAIN或EWOULDBLOCK的错误号。例:

import sys
import socket
import fcntl, os
import errno
from time import sleep

s = 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 sys
import socket
from time import sleep

s = 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

python 2022/1/1 18:47:47 有590人围观

撰写回答


你尚未登录,登录后可以

和开发者交流问题的细节

关注并接收问题和回答的更新提醒

参与内容的编辑和改进,让解决方法与时俱进

请先登录

推荐问题


联系我
置顶