2012-10-11 114 views
2

场景:
连接的客户机和server.The客户端连接之间建立关闭客户端被破坏。在服务器端,一些连接关闭被检测到,但有些不是。所以有一些socket描述符就像悬挂指针一样。选择这些返回错误的文件描述符错误,但不可能找到无效的fd。方法来处理错误的文件描述符错误

问题: 在上述情况下,当客户端连接不存在我应该怎么处理这些BAD FILE DESCRIPTORs。可我呼吁这些recv()

回答

1

select()的签名是:

int select(int nfds, fd_set *restrict readfds, 
      fd_set *restrict writefds, fd_set *restrict errorfds, 
      struct timeval *restrict timeout); 

不会在errorfds集给你这一个错误条件描述符的列表,如EBADF

您可以调用recv()或任何其他函数,该文件描述符带有文件描述符;您可能会从所调用的函数中返回EBADF错误(除非在检测到EBADF之前检测到其他错误情况)。

+0

recv()在这种情况下返回0,就好像与客户机的连接已关闭,但select为相同的套接字描述符返回错误的文件描述符。 – user1495948

+1

您可能需要区分系统认为的“坏文件描述符”和您认为的坏文件描述符。系统认为已关闭(或从未打开)的文件描述符不好。仅仅在读描述符的远端没有发送者的事实不是错误;文件描述符可能被报告为'准备好',并且当你读取它时,你会得到EOF指示(它是零字节读取的)。文件描述符不错;它永远不会返回任何数据。当'recv()'调用返回零时,您认为客户端已经消失。 –

+1

我关闭客户端的连接,同时在服务器端如果我选择fd获取集,我做recv()返回0,我断定客户端是closed.But在某些情况下选择将返回错误文件描述符error.Do你知道在哪种情况下选择返回描述符上的EBADF? – user1495948

1

我相信你搞砸了不同的情况。如果连接在客户端关闭,并且您在服务器端套接字上调用select(),则会触发FD_READ并且recv()将返回零,然后您可以在服务器端关闭套接字。

如果连接中断并且服务器未收到FIN信号,则需要在客户端&服务器和每个服务器端套接字上的计时器之间检测心跳,以检测TCP半开状态。

只有在已关闭的套接字上调用API时,才会出现“错误文件描述符”错误。

+0

所以你的意思是在TCP半开放的情况下select会返回一个EBADF? – user1495948

+1

否。对于TCP半开放套接字,select()将不返回任何内容,也不返回事件,也不写入事件。通常使用心跳计时器来检测TCP半开放式套接字,然后关闭它。 – ciphor

+0

为什么一个套接字描述符变得不好选择返回错误的文件描述符和recv返回0? – user1495948

相关问题