当 TCP keep-alive 断开连接时,我会得到什么套接字错误? [英] What socket error do I get when TCP keep-alive breaks the connection?

查看:23
本文介绍了当 TCP keep-alive 断开连接时,我会得到什么套接字错误?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一组保持活动状态的 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 of select(). Which one would select() return?]
    • After each iteration of the select() loop, you instead use the FD_ISSET macro to attempt a read() 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. Both read(2) and write(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 have EHOSTUNREACH delivered). [For more details on these cases, see Stevens, "Unix Network Programming, vol 1".]
    • 这篇关于当 TCP keep-alive 断开连接时,我会得到什么套接字错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆