2011-07-07 65 views
1

我寫了一個套接字服務器,運行在linux上,但這可能不是linux specifix。socket:不斷獲取POLLHUP半閉

我用poll()來檢查客戶端的狀態。我的客戶在發送請求後進行主動(半)關閉。服務器不斷得到POLLHUPPOLLERR,因爲客戶端半截。我也看到POLLRDHUP,所以我知道這實際上是半關閉的而不是連接關閉/重置。我的問題是,即使我從之前的調查中已經知道有一個半結束的情況,我總是會得到這些事件。

如何禁用此功能,以免再次收到該事件?我試圖做額外的read()並做一個shutdown(fd, SHUT_RD),但它似乎沒有幫助。我不希望poll在我已經處理的事件中醒來。

+0

我和你有類似的問題,我不想在poll()中獲得POLLHUP/POLLERR,只能得到我所選擇的事件。不知道這將如何完成 – Bionix1441

回答

3

停止在readfds集合中包含fd,一旦您收到一半關閉。除了半關閉之外,沒有什麼可以讀了。從這一點上,你唯一感興趣的就是'可寫'事件。

+0

readfds(和單獨的集合)只用於'select',但你是對的,我只是有一個錯誤,仍然被調查閱讀..我的頭撞在牆上:) –

0

只是忽略POLLHUP返回標誌。現有的代碼,如果正確的話,會做你想做的。

事實上,你將繼續從poll()(EJP的答案概述)得到半關閉是一個功能,而不是一個錯誤。它可以讓你像封閉文件一樣對待半封閉;這正是你想要的,因爲它允許你的應用程序讀取套接字緩衝區中的最後幾個字節而不是丟棄它們(這是TCP半關閉的正確語義)。

一旦達到「普通」文件結束,poll()將始終選擇文件描述符作爲準備讀取。然後圍繞poll()的循環被假設爲read()的數據直到看到文件結束,然後close()。忽略POLLHUP條件可讓您的程序在半關閉情況下使用相同的代碼完成相同的操作,並獲取套接字緩衝區中的最後一個字節。

同樣,您應該實施控制流程而不關心POLLHUP。如果(和只有在)你需要限制一個文件描述符(即目前無處可存放read()字節),然後從poll()集合中刪除該描述符,直到你再次告訴它(無限制),才能讀取「中斷」。所有數據都已經在套接字緩衝區(這是POLLHUP位指示的內容)的事實再次沒有什麼不同。

+0

對不起,但EJP有正確的答案。在我的情況下,我不能'關閉()';有很多數據要發送。如果我將fd保存在讀取集中,poll()將立即返回... –