当TCP保持活动断开连接时,会收到什么套接字错误?

我有一套TCP套接字保持活着(间隔1分钟),由select(2)循环(select读取)控制。

  • select(2)如果集合中的其中一个套接字发生保持活动超时返回一个错误?
  • 哪个错误会read(2)返回?

  • 如果为其选择的套接字之一发出错误,则select()本身不会返回错误。 [事实上,API不能以这种方式指示每个套接字错误,因为两个不同的套接字在select()的单个调用期间可能每个都会获得一个挂起的错误。 哪一个会select()返回?]
  • select()循环的每次迭代之后,您改为使用FD_ISSET宏在每个标记为可读的套接字上尝试read()
  • 任何时候套接字有一个挂起的错误集,它的读取事件(和写入事件)被发信号,并且select()返回,允许你立即拾取由于保持活动而导致的超时错误。 请注意,选择标记套接字进行读取并不表示有数据要读取,只是尝试读取不会被阻止。 如果套接字有一个待检错误,读取将不会被阻塞。 即使尝试处理任何数据, read(2)write(2)先检索套接字上的任何挂起错误。

当对O_NONBLOCK清除的输入函数的调用不会被阻塞时,描述符应被视为准备好读取,函数是否会成功传输数据。 (该函数可能会返回数据,文件结束指示,或者是一个指示被阻塞的错误以外的错误,并且在这些情况下,这些描述符都应该被视为可以读取。)[ POSIX:select() ]

  • 最后,返回什么错误? 至关重要的是,这取决于keepalive失败的方式。 如果另一端完全消失,您将得到ETIMEDOUT 。 如果发生数据包传送错误,您将通过取而代之(如果保活数据包得到一个ICMP错误答复,如“主机不可达”,您将有EHOSTUNREACH传递)。 [关于这些案例的更多细节,参见Stevens,“Unix Network Programming,vol 1”]。
  • select()FDSET中设置一个表示哪个套接字已被触发的位。 使用FD_ISSET宏来确定哪个套接字要求服务。