您好,登錄后才能下訂單哦!
這篇文章給大家介紹如何進一步的tcp使用,內容非常詳細,感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助。
以前對socket的了解僅僅局限于listen/connect/epoll/select/close等這些API的表面使用。其具體語義以及一些狀態都沒有深究。總覺得這樣寫代碼會出問題,今天咬咬牙把《tcp協議卷1》中的Tcp部分又看了一遍。發現由于對協議和API語義的了解不足,在程序中還是犯了不少錯誤。
TIME_WAIT狀態是tcp網絡編程中最不容易理解的地方。主動關閉的一方會經歷TIME_WAIT狀態, 這個狀態會經歷2MSL的時間。其目的就是為了可靠的實現TCP全雙工連接的終止和允許老的重復分組消逝在網絡中(具體可以參看UNP P37)。
TIME_WAIT的持續時間一般是1分鐘到4分鐘,如果在這段時間內涌入大量連接,然后服務器將其斷開,就會導致在服務器上殘留大量處理TIME_WAIT的連接,理論上這會嚴重拖慢系統的性能。
因此,只要條件允許,應該盡量讓客戶端來主動斷開連接。
由于服務器綁定的是固定端口,當重啟服務器時,只要還存在有通過這個固定端口接入進來的TIME_WAIT狀態的連接,就會導致bind失敗。因此服務器一定要為bind的socket設置SO_REUSEADDR屬性。
close的默認行為首先對描述符引用計數減一,如果引用計數為為0則執行close流程。即把該socket標記為關閉, 然后立即返回到調用進程,該socket不能再被調用進程使用。然而tcp將嘗試發送已經排隊等待發送到對端的任何數據,發送完閉后才會執行正常的tcp連接終止序列(即四次揮手). 這個行為可以通過SO_LINGER更改。
相比close, shutdown的行為則更為粗爆一些。
不管有多少進程在持有這個socket,一旦這個socket被shutdown, 那么所有的進程均不能再對此socket進行已經shutdown過的操作。shutdown可以分別關閉讀和寫。
shutdown寫時會將當前發送緩沖區中的數據都發送掉才會進行連接終止序列。
shutdown讀時會將當前接收緩沖區中的數據都請空。
在silly的實現中,我對于close的實現僅僅是粗爆的將所有發送緩沖區清空,然后關閉socket。
對比系統的close和shutdown函數可以發現, 這樣做是不對的,因為在應用層調用close時,有可能數據并沒有發完, 這樣就會有可能導致客戶端接收到的信息不完成,而造成其他bug.
關于如何進一步的tcp使用就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。