没有Python中阻塞套接字的信息的异常

时间:2016-01-29 15:01:28

标签: python sockets exception

我正在尝试从socket.recv()中找出一个神秘异常,该异常没有任何消息可以提供关于它来自何处的信息,或者为什么。这是在Windows 7,Python 2.7。

我创建了一个这样的阻塞套接字:

self.client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.client.settimeout(5)

我连接到一个流出数据的设备。我从不通过这个插座发送任何东西,我只收到。所以我在循环中调用select:

while(True):
    # Process commands from the GUI. These can include requests to
    # connect, disconnect, or quit
    quitting = self.processCmds()
    if quitting == True:
        print 'exiting'
        return
    try:
        rlist, wlist, errlist = select.select([self.client], [], [self.client], 5)
        if self.client in errlist:
            self.reconnect()
            continue
        elif self.client in rlist:
            # We have a message.
            msg = recvall(self.client, MESSAGE_LENGTH)
                if msg == None:
                    self.reconnect()
                    continue

到目前为止,这么好。 rcvall()以你期望的方式循环,尝试读取请求的字节数:

def recvall(conn, count):
    buf = b''
    numIterations = 0
    while count:
        try:
            recvString = conn.recv(count)
        except:
            # OH NO SOMETHING BAD HAPPENED!
            e = sys.exc_info()[0]
            return None
        if not recvString:
            # the socket has been closed by the remote end
            return None
        if (len(recvString) > 0):
            buf = buf + recvString
            count = count - len(recvString)
        else:
            # If the other guy has sent no bytes, don't wait forever
            numIterations += 1
            if numIterations > 100:
                return None
    return buf

因此,如果出现任何问题,recvall()将返回None,告诉调用者关闭现有连接并打开一个新连接。

这大约工作了大约8个小时左右,但后来我在日志中看到了重新连接尝试的流,没有成功。在经历了一些狩猎和啄食断点之后,我了解到我们在rcvall()中遇到了异常,其中的评论OH NO SOMETHING BAD HAPPENED!是。但是当我尝试检查调试器中的异常对象时,其消息成员为None。事实上,它的所有成员都是无,所以不知道是谁提出它或为什么。

这有几个奇怪的事情。在select()已经告诉我套接字没有错误并且包含数据之后发生异常。调用select()和调用recvall()之间会出现问题吗?这是可能的,但似乎不太可能。

第二,有没有人见过来自socket.recv的这种奇怪的异常?有什么线索可以找到它吗?

1 个答案:

答案 0 :(得分:0)

看起来远程端强行关闭连接,但Visual Studio + PVTS很有趣地显示有关异常的所有信息。此外,显然,在Windows中,您会收到另一端通过异常关闭连接的通知,而不是像文档所说的那样recv()返回None。

我禁用了异常处理程序并在没有IDE的情况下运行,让Python打印回溯。有时,Visual Studio很有趣,可以通过例外情况向您讲述整个故事。这就是我得到的:

Exception in thread Thread-2:
Traceback (most recent call last):
  File "C:\Python27\lib\threading.py", line 810, in __bootstrap_inner
    self.run()
  File "../shared\retrieveMessage.py", line 184, in run
    msgLength = recvall(self.client, 2)
  File "../shared\retrieveMessage.py", line 52, in recvall
    recvString = conn.recv(count)
error: [Errno 10054] An existing connection was forcibly closed by the remote host

所以看起来对方毕竟是行为不端。