2010-05-20 136 views
5

我的linux應用程序正在執行非阻塞TCP連接系統調用,然後使用epoll_wait來檢測三次握手完成。 有時epoll_wait返回兩個POLLOUT & POLLERR事件爲同一套接字描述符設置。非阻塞tcp連接epoll

我想了解TCP級別發生了什麼。我無法按需重現它。我的猜測是,在我的事件循環內部的兩個調用epoll_wait之間我們有一個SYN + ACK/ACK/FIN序列,但是我再次無法再現它。

回答

4

如果連接失敗,可能會發生這種情況 - 例如,「連接超時」(對於進行非阻塞連接的套接字,當連接操作完成時連接操作已成功和失敗的結果都會被設置爲POLLOUT )。

POLLOUT成爲了本插座組件,使用getsockopt(sock, SOL_SOCKET, SO_ERROR, ...)以檢查是否連接成功(在SO_ERROR套接字選項是在這種情況下0,否則說明爲什麼連接失敗)。

2

以下是關於non-blocking tcp connect()的一些很好的信息。

當檢測到套接字錯誤時(即連接關閉/拒絕/超時),epoll將返回帶有POLLERR的已註冊感興趣事件POLLIN/POLLOUT。因此,如果您註冊了POLLOUT,epoll_wait()將返回POLLOUT | POLLERR,如果註冊了POLLIN | POLLOUT,則返回POLLIN | POLLOUT | POLLERR。

僅僅因爲epoll返回POLLIN並不意味着會有數據可讀取,因爲recv()可能只是從非阻塞connect()調用返回錯誤。我認爲epoll用POLLERR返回所有已註冊的事件,以確保程序調用send()/ recv()/ etc。並獲取套接字錯誤。某些程序從不檢查POLLERR/POLLHUP,只在下一次send()/ recv()調用時捕獲套接字錯誤。