【问题标题】:What are the error codes that mean the socket connection is lost?表示套接字连接丢失的错误代码是什么?
【发布时间】:2012-11-10 20:49:28
【问题描述】:

我在用 Python 编写 TCP 服务器时注意到,当一端或另一端意外停止时,在不同的条件下会发生一些错误。

例如,有时我得到“管道损坏”(errno.EPIPE),有时“连接中止”(errno.CONNABORTEDerrno.WSAECONNABORTED)。还有跨操作系统the codes are not the same 的东西,但我猜Python 的errno 模块可以处理这个问题。

我搜索了很多socket连接错误代码的含义列表,没有找到我要查找的内容。

到目前为止,我得到的是这样的:

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 连接?

【问题讨论】:

    标签: python sockets networking tcp


    【解决方案1】:

    当您尝试从 python 中的关闭套接字读取时,通常不会引发异常。你应该一直读到recv 返回空字符串。

    写入关闭的套接字当然会引发一个 Execption (socket.error),它包含操作系统引发的错误号。

    但您不应该过多关注错误代码。 Python 不是 C,或者正如 tutorial 在谈论非阻塞套接字时所说的那样:

    您可以检查返回码和错误码,通常会让自己发疯。如果你不相信我,有时间试试。你的应用程序会变得很大、有问题并且会占用 CPU。所以让我们跳过那些脑残的解决方案,把它做好。

    ...

    【讨论】:

    • 感谢您的链接,尽管我搜索了很多,但我从未见过它!我很确定我在这两种情况下都会遇到错误,但是现在我阅读了教程,我认为这是因为我使用的是由SocketServer 类(rfilewfile)提供的缓冲阅读器......也许我会使用另一种方法(recvsend,也可以在该类中使用)。是的,我知道最好让 Python 处理线程中的异常,但我想回溯看起来不太好,这是项目的一部分,所以我宁愿尽可能自定义消息。跨度>
    • 在函数正常返回后必须检查错误代码(在没有异常的语言中,例如 C)和检查函数调用引发的异常对象上的 errno 是有区别的。前者是那种容易出错的事情,有异常的语言试图减轻程序员的负担。后者对于了解发生了什么基本上是必不可少的。在某些情况下,知道发生了与您希望发生的事情不同的某件事就足够了,但在大多数情况下,您实际上需要知道发生了什么。
    • 谢谢你们两个 :) 我会让它失败然后忽略它。
    【解决方案2】:

    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 文档都多。

    【讨论】:

    • 谢谢,我不知道在哪里搜索这些,因为 Python 文档对我来说似乎不完整。不过,好的方法似乎是让异常发生而不试图进一步分析它。
    • 我希望你会发现这是真的,直到它不是真的。
    猜你喜欢
    • 1970-01-01
    • 2011-05-19
    • 1970-01-01
    • 2014-10-11
    • 2017-05-07
    • 2016-05-16
    • 2021-12-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多