Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
402 views
in Technique[技术] by (71.8m points)

c - 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).

  • 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?
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

  • 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.

    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".]

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...