簡體   English   中英

C#中如何高效判斷一個socket的狀態?

[英]How to efficiently determine the status of a socket in C#?

我有一個從客戶端接收數據的服務器,我希望能夠確定套接字是否仍然連接。

我正在使用以下 function 來確定狀態(來源):

bool SocketConnected(Socket s)
{
    bool part1 = s.Poll(1000, SelectMode.SelectRead);
    bool part2 = (s.Available == 0);
    if (part1 && part2)
        return false;
    else
        return true;
}

但是,當 RTT(服務器/客戶端之間)很高(~300 毫秒)並且變化(+ - 60 毫秒)時,我的應用程序“崩潰”。 從調試中我發現這是由於套接字被標識為未連接(SocketConnected()返回false)。 但我知道,套接字仍然連接,因為我可以看到客戶端流式傳輸從服務器請求的內容,並且服務器接收由 Wireshark 捕獲的數據。

我應該增加輪詢的時間(但我不想阻止其他操作)還是將 Socket.Connected 屬性與 SocketConnected() 一起使用? 在不穩定的環境中確定套接字狀態的最有效方法是什么?

不幸的是,您找到並引用的問題和答案充滿了糟糕的建議,並且沒有什么真正有建設性的問題可以說。 TCP 等面向連接的協議專門設計用於盡可能長時間地延遲錯誤,以盡可能多地解決潛在的間歇性傳輸問題(網絡電纜被拔出、無線連接重置等),以盡量減少這些問題的影響在實際連接上。

對所引用問題的每一個答案都會破壞這一一般策略,或者未能以有用的方式解決問題,或者兩者兼而有之。

處理這種情況的唯一正確方法是假設套接字在您期望的連接 state 中(基於您自己的代碼操作),同時確保您的代碼在每個適當的使用點都有異常處理的插座。 沒有其他辦法。

您可以查看Connected屬性,但這不會告訴您任何有用的信息。 檢查屬性后,套接字可能會在一納秒內轉換為未連接的 state。 您也不應該使用Poll()等基於“選擇”的方法,因為這些方法效率低下,並且不會隨連接數量而擴展。

每個聯網程序都可以成功使用異步 I/O。 如果程序有 GUI(例如 Winforms、WPF 等),那么您甚至可以這樣做,同時仍然在 UI 線程中進行所有實際數據處理(這讓您不必太擔心多線程問題......使用現代的async / await習慣用法會更好,但您也可以只使用“老派”技術,如Control.BeginInvoke()Dispatcher.InvokeAsync() )。

因此,遵循這些准則,唯一一次套接字的連接性會以任何有意義、有趣的方式改變 state 是當這種情況有意發生時,然后通過正常處理優雅關閉來檢測,即讀取操作以零字節完成結果,或者由於錯誤而發生,在這種情況下,您的異常處理將檢測到意外斷開的 state。

如果沒有適當的異常處理,您將無法成功編寫無缺陷的網絡 I/O 代碼,因此只有依賴該異常處理來處理所有異常情況才有意義。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM