我注意到在用Python编程TCP服务器时,当一端或另一端意外停止时,在不同条件下会发生一些错误。
例如,有时我得到“管道损坏”(errno.EPIPE
),有时“连接已中止”(errno.CONNABORTED
或errno.WSAECONNABORTED
)。操作系统the codes are not the same之间也存在问题,但我猜Python的errno
模块会处理这个问题。
我搜索了很多套接字连接错误代码的含义列表,却没有找到我要找的东西。
到目前为止我所拥有的是:
try:
# write or read operation
except socket.error as e:
if e.errno in (errno.EPIPE, errno.ECONNABORTED, errno.WSAECONNABORTED):
print 'Connection lost with server...'
到目前为止,一切工作都很顺利,甚至在添加最后一个之前,我在Windows上遇到了问题,并添加了它,所以我担心可能会出现一些我无法处理的情况。此外,有时,它只是没有抛出错误并继续读取空行(使用recv
)和坏文件描述符等。
SocketServer
类提供这样的东西吗?或者TCP连接一般吗?
答案 0 :(得分:1)
当您尝试从python中的已关闭套接字读取时,通常不会引发异常。你应该阅读直到recv
返回emty字符串。
写入一个封闭的套接字当然会引发一个Execption(socket.error
),它包含操作系统引发的错误号。
但你不应该过多地关注错误代码。 Python不是C,或者tutorial在讨论非阻塞套接字时提到它:
您可以查看返回代码和错误代码,通常会让自己变得疯狂。如果你不相信我,请尝试一下。你的应用程序将变得越来越大,越来越多,吸收CPU。因此,让我们跳过脑死亡的解决方案并做正确的事。
...
答案 1 :(得分:1)
Python套接字模块是BSD套接字API的一个很薄的包装器。通常,您可以通过查看C BSD套接字API的手册页找到可能的错误代码(errno值)的文档。例如,man 2 recv
:
ERRORS
These are some standard errors generated by the socket layer. Additional errors
may be generated and returned from the underlying protocol modules; see their
manual pages.
EAGAIN or EWOULDBLOCK
The socket is marked nonblocking and the receive operation would
block, or a receive timeout had been set and the timeout expired before
data was received. POSIX.1-2001 allows either error to be returned for
this case, and does not require these constants to have the same value,
so a portable application should check for both possibilities.
EBADF The argument sockfd is an invalid descriptor.
ECONNREFUSED
A remote host refused to allow the network connection (typically because
it is not running the requested service).
EFAULT The receive buffer pointer(s) point outside the process's address space.
EINTR The receive was interrupted by delivery of a signal before any data were
available; see signal(7).
EINVAL Invalid argument passed.
ENOMEM Could not allocate memory for recvmsg().
ENOTCONN
The socket is associated with a connection-oriented protocol and has not
been connected (see connect(2) and accept(2)).
ENOTSOCK
The argument sockfd does not refer to a socket.
手动页面本身通常不完整,但它们比任何Python文档都包含更多案例。