当TCP keep-alive中断连接时,我会得到什么套接字错误?

CCo*_*der 9 c sockets linux tcp

我有一组带有保持活动的TCP套接字(间隔1分钟),由select(2) 循环控制(选择读取).

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

Nic*_*son 5

  • select()如果为其选择的其中一个套接字发出错误信号,则本身不会返回错误.[实际上,API不能以这种方式指示每插槽错误,因为两个不同的套接字可以在单次调用期间各自获得挂起错误select().哪一个会select()回来?]
  • 在循环的每次迭代之后select(),您使用FD_ISSET宏来尝试read()在每个标记为可读的套接字上.
  • 每当套接字具有挂起的错误集时,它的读取事件(和写入事件)都会发出信号并select()返回,这样您就可以立即获取由于保持活动而导致的超时错误.请注意,选择标记套接字以进行读取并不表示存在要读取的数据,只表示读取的尝试不会阻止.如果套接字有待检索的挂起错误,则读取不会阻止.无论read(2)write(2)第一甚至试图以处理任何数据之前检索套接字上任何挂起的错误.

    当对具有O_NONBLOCK clear的输入函数的调用不会阻塞时,该函数将成功传输数据时,应认为描述符已准备好进行读取.(该函数可能返回数据,文件结束指示或除了表示被阻止的错误之外的错误,并且在每种情况下,描述符都应被视为已准备好进行读取.)[ POSIX:select() ]

  • 最后,返回了什么错误?至关重要的是,这取决于保持活动失败的方式.ETIMEDOUT如果另一端完全消失,你会得到的.如果发生数据包传递错误,您将通过相应的方式(因此,如果保持活动数据包获得ICMP错误回复,如"主机无法访问",则您将已EHOSTUNREACH交付).[有关这些案例的更多详细信息,请参阅Stevens,"Unix网络编程,第1卷".]