2010-10-22 245 views
0

系統背景: 它基本上是一個客戶端/服務器應用程序。服務器是嵌入式設備,客戶端是用C++開發的Windows應用程序。套接字重新連接失敗

問題:在運行了大約一週後,客戶端/服務器之間的通信斷開,
因爲這樣服務器無法連接回客戶端並需要重新啓動才能恢復。看起來像系統正在遇到套接字重新連接問題。此外,網絡有時會經歷間歇性故障。在遠端

  • 端口

    1. 突然終止鎖定

    想如何清理插座或關機乾淨,以便重新連接正常情況提出了一些建議。其他替代方案?

    感謝, 侯賽因

  • +0

    祝你好運,如果你得到的迴應! – Chubsdad 2010-10-22 10:51:43

    +0

    通常,它是連接到服務器的客戶端,而不是其他方式。簡單地關閉現有套接字並打開另一個套接字有什麼問題? – Dialecticus 2010-10-22 11:04:06

    +0

    @Dialecticus - 沒有什麼,提供這種情況下的邏輯是正確的。雖然很難獲得100%的權利。 – 2010-10-22 11:12:24

    回答

    2

    它聽起來並不像你是在一個位置,很容易地編寫壓力測試應用程序更迅速帶外的複製本,這是我通常建議。務實的解決方案可能是在您認爲系統最忙或出現問題時定期重新啓動服務器和客戶端。這聽起來像是作弊,但我參與的許多生產系統都採用這種方法來最大化系統正常運行時間。

    我的首選解決方案是抽象服務器和客戶端套接字代碼(希望您的設計可以在不需要太多工作的情況下完成)並使用它來實現客戶端和服務器測試應用程序,這些應用程序只能用於壓力測試通過在短時間內模擬大量正常的套接字流量來實現套接字代碼 - 這有助於識別隨時間推移可能導致問題的時序窗口和邊緣情況,並且可能加快獲取可調試再現的過程 - 您可以模擬網絡錯誤在您的測試代碼中定期刪除客戶端或服務器上的套接字。

    進一步採取戰略方面的一步是確保您在客戶端和服務器端的套接字處理程序中具有良好的診斷功能。跟蹤套接字的打開和關閉,特別關注您的套接字錯誤並重新連接路徑,因爲您知道網絡不可靠。確保日誌以時間戳順序輸出。像這樣簡單的事情可能會很快顯示出什麼錯誤或情況會引發您的問題。您可以使用上面提到的測試應用程序快速確保日誌正確並完整。

    你可能想要檢查的一件事是你沒有被重用地址的能力缺乏打擊。有時,當套接字被關閉時,它不能立即重新用於重新連接嘗試,因爲在一端或另一端仍有剩餘活動。您可以通過在您的套接字上嘗試使用SO_REUSEADDR和SO_LINGER來解決此問題(基於我的Windows/Winsock體驗)。不過,我的第一個重點是確保客戶端和服務器上的套接字代碼正確處理所有錯誤和主線情況,然後再擔心這一點。

    1

    一個常見問題是,當連接斷開時,操作系統將以TIME_WAIT狀態保持打開狀態。如果您想重新啓動服務器套接字,將無法直接重新打開相同的端口,因爲它仍然存在於操作系統中。 爲避免這種情況,您需要設置參數SO_REUSEADDR,以便操作系統允許您重新使用該端口(如果它處於服務器套接字的TIME_WAIT狀態)。

    例子:

    int optval=1; 
    // set SO_REUSEADDR on a socket to true (1): 
    setsockopt(s1, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof optval); 
    
    0

    我遇到加密連接類似的東西。我相信在我的情況下,這是因爲客戶端在4分鐘的FIN_WAIT期間內斷開連接並重新連接。初始連接被回收(通過操作系統),服務器看不到退出。當客戶端失去連接時,SSL身份驗證會丟失,客戶端會嘗試重新進行身份驗證。這是服務器認爲會話中間的事情。然後服務器掛在客戶端上。我認爲服務器SSL代碼認爲這是一個人在中間攻擊或只是感到困惑,並關閉連接。

    +0

    這都不是可能的。 FIN_WAIT時間段影響首先結束的結束,而不是首先結束結束的結束。由於傳入的SYN以及新的TCP序列號,服務器會將其視爲新的TCP連接。在SSL級別,SSL會話可以恢復。你的問題在別處。 – EJP 2010-10-23 02:00:39

    +0

    我認爲你錯了。我調試關閉客戶端(一個Windows服務)並重新啓動它。服務器從未收到連接關閉事件,並且相同的連接被重用。 – Jay 2010-10-25 14:09:54