当 TCP keep-alive 断开连接时,我会得到什么套接字错误? [英] What socket error do I get when TCP keep-alive breaks the connection?
问题描述
我有一组保持活动状态的 TCP 套接字(间隔 1 分钟),由 控制select(2)
循环(选择读取).
I have a set of TCP sockets with keep-alive (interval 1 min), controlled by a select(2)
loop (selecting for read).
- 如果集合中的一个套接字发生了保持活动超时,
select(2)
是否会返回错误? read(2)
会返回哪个错误?
- Will
select(2)
return an error if keep-alive timeout has happened for one of the sockets in the set? - Which error will
read(2)
return?
推荐答案
select()
如果它选择的套接字之一发出错误信号,则它本身不会返回错误.[实际上,API 无法以这种方式指示每个套接字的错误,因为在一次select()
调用期间,两个不同的套接字可能会分别获得一个未决错误.select()
会返回哪一个?]- 在
select()
循环的每次迭代之后,您改为使用 FD_ISSET 宏在每个标记为可读的套接字上尝试read()
. - 每当套接字设置了未决错误时,它的读取事件(和写入事件)都会发出信号,并且
select()
返回,允许您获取由于保持而导致的超时错误-马上活了.请注意,选择标记套接字进行读取并不表示有数据要读取,仅表示读取尝试不会阻塞.如果套接字有待检索的未决错误,则读取不会阻塞.read(2)
和write(2)
在尝试处理任何数据之前首先检索套接字上的任何未决错误.select()
itself does not return an error if an error is signalled for one of the sockets it is selecting for. [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 ofselect()
. Which one wouldselect()
return?]- After each iteration of the
select()
loop, you instead use the FD_ISSET macro to attempt aread()
on each socket marked readable. - 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. 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. Bothread(2)
andwrite(2)
first retrieve any pending error on the socket before even attempting to handle any data.当使用 O_NONBLOCK 清除对输入函数的调用不会阻塞时,无论该函数是否成功传输数据,都应认为描述符已准备好读取.(该函数可能返回数据、文件结束指示或错误,而不是表明它被阻塞的错误,在这些情况下,描述符应被视为准备好读取.)[POSIX:select()]
- 最后返回了什么错误?至关重要的是,这取决于保活失败的方式.如果另一端完全消失,您将获得
ETIMEDOUT
.如果发生数据包传送错误,您将改为通过(因此,如果保持活动数据包收到 ICMP 错误回复,例如主机无法访问",您将获得EHOSTUNREACH
传送).[有关这些情况的更多详细信息,请参阅 Stevens,Unix 网络编程,第 1 卷".]
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. (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()]
- Finally, what error is returned? Crucially, it depends on how the keepalive failed. You'll get
ETIMEDOUT
if the other end vanishes totally. 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 haveEHOSTUNREACH
delivered). [For more details on these cases, see Stevens, "Unix Network Programming, vol 1".]
这篇关于当 TCP keep-alive 断开连接时,我会得到什么套接字错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!