1. 程式人生 > >SOCKET客戶端與服務端長時間通訊後,會連線不上服務端的問題,以及server端UDP丟包的問題

SOCKET客戶端與服務端長時間通訊後,會連線不上服務端的問題,以及server端UDP丟包的問題

人生第一篇部落格,希望能以一個好的開始,持之以恆下去!

這兩天在做有關負載均衡的一個專案,期間在除錯時遇到了一個問題:客戶端與服務端依靠socket通訊,但是長時間通訊後,會發生客戶端連線不上服務端的狀況。而後查詢了一些資料後,終於搞清楚問題的緣由了,在此和大家分享一下!

除錯時的環境是:一個客戶端,有多個服務端,那麼客戶端去連線哪個服務端是由負載均衡演算法計算出來的,將眾多server中負載最小的一個server的IP地址返回給客戶端,而後client再去連線那臺最優的server。

直接點說,問題的原因是客戶端短時間內大批量的連線服務端後,系統沒有多餘的埠為後續的連線使用了。

當客戶端與服務端通訊時,系統會分配給客戶端一個埠,但是在使用者呼叫closesocket()之後,這些埠並不會close掉,而是處於TIME_WAIT狀態。而TIME_WAIT狀態的埠是無法被下面的連線使用的,而TIME_WAIT狀態並不會一直持續下去,它會持續2個MSL時間,4分鐘。這也就是客戶端為什麼在短時間內大批量的與服務端通訊後,會連不上server端。

埠的TIME_WAIT狀態,是TCP連線斷開時肯定會出現的狀態,是協議自我保護的一部分,我們當然可以調整TIME_WAIT等待的時間,但是我覺得,既然協議中這樣設定了時間就一定有他的用意,根據一時的所需而去修改,肯定不理智,所以我就要減少建立連線的次數,以減少對埠的消耗。

同樣的問題在server端也有可能會存在的。

補充另一個問題。

通過UDP在網路群組中做“心跳”功能時,吃時間執行後,出現本機只能收到本機發送的資訊,而無法收到網路中其他的機器傳送的資訊。

工作的環境是:網路群組中的每一個server都會定時將自身的資訊UDP廣播出去,同時也在不斷的接受資訊。

出現問題的原因,我想了一下在於三點吧(領導人講話,一般至少講三點~~~)。第一,通過UDP廣播出去的資訊在網路中存在是有時間限制的;第二:server接受資訊遠比傳送一條資訊來的慢;第三:網路延時。系統會將從網路中收集到的資訊儲存一塊記憶體中,然後,使用者的recv()函式開始從記憶體中一條一條的取資訊。但是由於取資訊的速度“太慢”(相對而言),這就使得第n條資訊,還沒來得及被recv()到,就已經被刪除了,因為它已經超過了存活時間。至於為什麼還能收到本機發送的資訊,而只是收不到網路中其他server傳送的資訊,並不是由於本機socket傳送的資訊不會丟失,同樣的超過了存活時間,一樣會被刪除,只是由於網路延時的原因,記憶體中存活的本機資訊,遠多於網路中其他server傳送的資訊。

謝謝大家!我還在學習ing,歡迎大家批評指正!!!