简体   繁体   English

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

[英]What socket error do I get when TCP keep-alive breaks the connection?

I have a set of TCP sockets with keep-alive (interval 1 min), controlled by a select(2) loop (selecting for read). 我有一组带有保持活动的TCP套接字(间隔1分钟),由select(2)循环控制(选择读取)。

  • Will select(2) return an error if keep-alive timeout has happened for one of the sockets in the set? 如果集合中的一个套接字发生了保持活动超时,那么select(2)返回错误吗?
  • Which error will read(2) return? 哪个错误会read(2)返回?

  • select() itself does not return an error if an error is signalled for one of the sockets it is selecting for. 如果为其选择的其中一个套接字发出错误信号,则select()本身不会返回错误。 [Indeed, the API can't indicate per-socket errors this way, because two different sockets could each acquire a pending error during a single call of select() . [实际上,API无法以这种方式指示每插槽错误,因为在单次调用select()期间,两个不同的套接字都可以获取挂起错误。 Which one would select() return?] 哪一个会select()返回?]
  • After each iteration of the select() loop, you instead use the FD_ISSET macro to attempt a read() on each socket marked readable. 在每次迭代select()循环之后,您改为使用FD_ISSET宏在每个标记为可读的套接字上尝试read()
  • Any time a socket has a pending error set, its read event (and write event) are signalled, and select() returns, allowing you to pick up timed-out errors due to keep-alive immediately. 每当套接字具有挂起的错误集时,它的读取事件(和写入事件)都会发出信号,并且select()返回,这样您就可以立即获取由于保持活动而导致的超时错误。 Note that select marking a socket for read does not indicate that there is data to read, only that an attempt to read will not block. 请注意,选择标记套接字以进行读取并不表示存在要读取的数据,只表示读取的尝试不会阻止。 If the socket has a pending error to retrieve, reading will not block. 如果套接字有待检索的挂起错误,则读取不会阻止。 Both read(2) and write(2) first retrieve any pending error on the socket before even attempting to handle any data. read(2)write(2)都会在尝试处理任何数据之前首先检索套接字上的任何挂起错误。

    A descriptor shall be considered ready for reading when a call to an input function with O_NONBLOCK clear would not block, whether or not the function would transfer data successfully. 当对具有O_NONBLOCK clear的输入函数的调用不会阻塞时,该函数将成功传输数据时,应认为描述符已准备好读取。 (The function might return data, an end-of-file indication, or an error other than one indicating that it is blocked, and in each of these cases the descriptor shall be considered ready for reading.) [ POSIX:select() ] (该函数可能返回数据,文件结束指示或除了表示被阻止的错误之外的错误,并且在每种情况下,描述符都应被视为已准备好进行读取。)[ POSIX:select() ]

  • Finally, what error is returned? 最后,返回了什么错误? Crucially, it depends on how the keepalive failed. 至关重要的是,这取决于保持活动失败的方式。 You'll get ETIMEDOUT if the other end vanishes totally. 如果另一端完全消失,你会得到ETIMEDOUT If a packet delivery error occurs, you'll get that through instead (so if the keep-alive packet gets an ICMP error reply, like "host unreachable", you'll have EHOSTUNREACH delivered). 如果发生数据包传递错误,您可以通过它来实现(因此,如果保持活动数据包获得ICMP错误回复,例如“主机无法访问”, EHOSTUNREACH发送EHOSTUNREACH )。 [For more details on these cases, see Stevens, "Unix Network Programming, vol 1".] [有关这些案例的更多详细信息,请参阅Stevens,“Unix网络编程,第1卷”。]

select() sets a bit in the FDSET that indicates which socket has triggered. select()FDSET中设置一个位,指示哪个套接字已触发。 Use FD_ISSET macro to determine which socket asked for service. 使用FD_ISSET宏来确定要求服务的套接字。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM