首先,值得一提的是,在大多数情况下,最好在主处理程序循环中处理此问题,您可以简单地测试EOF(由
socket.recv()
接收到的空字符串)。然而,我遇到了需要测试这个的情况,以下方法似乎比传递另一个回调函数到线程中获取此状态更好,等等。
以下是我正在使用的内容,但我非常陌生,因此如果有更好或更有效的方法,请提供反馈,我将更新此答案。
似乎最好的方法是检查
getpeername()
(在此处测试
socket.recv()
是不好的,因为我们的测试会改变缓冲区,例如)。
返回远程端点的地址。对于IP套接字,地址信息是一对(hostaddr,port)。
如果失败,则会引发socket.error
[Errno 9] Bad file descriptor.
。
def is_socket_valid(socket_instance):
""" Return True if this socket is connected. """
if not socket_instance:
return False
try:
socket_instance.getsockname()
except socket.error as err:
err_type = err.args[0]
if err_type == errno.EBADF:
return False
try:
socket_instance.getpeername()
except socket.error as err:
err_type = err.args[0]
if err_type in [errno.EBADF, errno.ENOTCONN]:
return False
return True
注意:我在这里加入了第一个if检查,因为我正在测试可能为None的属性。
- 虽然不够明确,但在我的测试中似乎很准确。
- 原始问题提到想知道未连接的原因。这并没有解决这个问题。
此外,另一个答案提到fileno()
如果套接字的本地端关闭,则返回负数。我得到了相同的错误9。无论如何,在这种情况下,这并没有测试另一侧。
>>> s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
>>> s.fileno()
10
>>> s.close()
>>> s.fileno()
---------------------------------------------------------------------------
error Traceback (most recent call last)
----> 1 s.fileno()
/tools/package/python/2.7.13/lib/python2.7/socket.pyc in meth(name, self, *args)
226
227 def meth(name,self,*args):
--> 228 return getattr(self._sock,name)(*args)
229
230 for _m in _socketmethods:
/tools/package/python/2.7.13/lib/python2.7/socket.pyc in _dummy(*args)
172 __slots__ = []
173 def _dummy(*args):
--> 174 raise error(EBADF, 'Bad file descriptor')
175
176 send = recv = recv_into = sendto = recvfrom = recvfrom_into = _dummy
error: [Errno 9] Bad file descriptor