我正在尝试从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的这种奇怪的异常?有什么线索可以找到它吗?
答案 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
所以看起来对方毕竟是行为不端。