2011-04-29 86 views
0

我已經編寫了基於iocp機制的用於管理網絡通信的複雜庫。問題在於,當服務器通過調用API方法closesocket()關閉連接時,這些信息有時會以秒或甚至分鐘的形式傳輸給客戶端。我檢測關閉連接的代碼看起來像這樣(簡化):GetQueuedCompletionStatus延遲

ok = GetQueuedCompletionStatus(completion_port, &io_size, (PULONG_PTR)&context, &overlapped, 40); 

if (!ok) { 
    // something went broken 
    DWORD err = GetLastError(); 
    if (err == ERROR_CONNECTION_REFUSED) { 
     // connection failed 
    } else if (err == ERROR_SEM_TIMEOUT) { 
     // connection timeout 
    } else if (err == ERROR_NETNAME_DELETED) { 
     // connection closure - point of interest 
    } else if (err != WAIT_TIMEOUT) { 
     // unknown error 
    } 
} else { 
    // process incomming or outgoing data 
} 

這究竟是爲什麼?我需要立即知道連接關閉,以便能夠連接到備份服務器(不是那麼重的負載 - 因此發生斷開連接)。

+0

不直接關係到你的問題,但你應該檢查的重疊處理函數中的值以及返回代碼。當重疊== NULL就意味着失敗GetQueuedCompletionStatus時,重疊的時候!= NULL這意味着I/O請求失敗。 – 2011-04-29 21:27:44

回答

0

我試圖與靈兒參數進行試驗,如萊恩寫道,但這並沒有幫助。在closesocket()之前添加了shutdown()函數的調用幫助了我。在分析到達客戶端網絡接口的數據包(使用WireShark)後,我發現RST數據包被FIN數據包所取代。奇怪的是,RST數據包沒有延遲。因此操作系統知道連接關閉,而是由一些未知的原因,這個信息被轉移到應用層非常滯後。我測量了10秒到4分鐘之間的延遲。

0

你是如何關閉連接的?

如果你只是打電話closesocket()那麼你正在啓動關閉序列,這將試圖確保當前等待處理的所有數據將到達目的地。這可能需要一些時間,尤其是在網絡連接已經過載並且數據報已經丟失並且正在進行TCP重傳的情況下。

如果您想立即關閉連接,並丟失任何待處理數據,請將逗號設置爲0,然後關閉套接字。這將在連接上發出RST,你會更快。