正常連線:
客戶端: closed–syn_send—established
伺服器: listen—syn收到—-established
正常關閉
客戶端:established—fin_wait_1—fin_wait_2—time_wait–closed
服務端:established–close_wait—-last_ack—closed
同時開啟
syn_send—–syn收到—-established
同時關閉
established—fin_wait_1—closing—time_wait–closed
典型的時序圖如下
注:從其他位址摘的,好像有點問題,需要根據檢視tcp/ip卷一詳解修訂下
關閉時序圖另外一種表示方式
伺服器保持了大量time_wait狀態
一般情況下,作為客戶端請求第三方服務,沒有進行主動關閉。
伺服器保持大量close_wait狀態
伺服器接收客戶端的關閉操作,沒有進行關閉。
一、解決:
原因是因為呼叫serversocket類的accept()方法和socket輸入流的read()方法時會引起執行緒阻塞,所以應該用setsotimeout()方法設定超時(預設的設定是0,即超時永遠不會發生);超時的判斷是累計式的,一次設定後,每次呼叫引起的阻塞時間都從該值中扣除,直至另一次超時設定或有超時異常丟擲。
比如,某種服務需要三次呼叫read(),超時設定為1分鐘,那麼如果某次服務三次read()呼叫的總時間超過1分鐘就會有異常丟擲,如果要在同乙個socket上反覆進行這種服務,就要在每次服務之前設定一次超時。
二、規避:
調整系統引數,包括控制代碼相關引數和tcp/ip的引數;
具體措施見:參考資料1
linux核心對連線的處理過程
核心會為處於listening狀態的socket維護兩個佇列,乙個是已經完成了三次握手的佇列(tcp鏈結處於tcp狀態機中的established狀態),乙個是還沒有完成三次握手的佇列(tcp鏈結處於tcp狀態機中的syn_rcvd狀態)。
當三次握手完成後,tcp鏈結就建立了,將這個成員從未完成佇列已到完成佇列(accept()是阻塞的,若已完成佇列有鏈結,則返回的已完成佇列的首個成員)。未完成佇列中的成員有75秒生存時間。listen()的第二個引數指的是這兩個佇列的成員總數。
若是佇列已滿,server對新進來的鏈結不予處理,client的connect()會重新嘗試鏈結。
有一種dos(denial of service)攻擊叫syn flooding,它是某個clinet瘋狂的傳送syn,嘗試與server建立鏈結,那server佇列滿了之後,正常的lient的鏈結請求就不能處理了。
協議頭以及伺服器應用
服務端中狀態機的唯一表示:
1. 傳送方ip+傳送方埠+應用層的序列號(非同步事務必須支援)
2. 傳送ip+傳送方埠+接收ip+接收埠+應用層的序列號(非同步事務必須支援)
參考資料1:
參考資料2:
TCP協議總結
mss maximum segment size 只能出現在syn包中,通訊雙方在syn包和syn ack包中互相通告各自能接收的mss syn包不能攜帶data,占用seq ack包能攜帶data,攜帶data時占用seq,不攜帶data時不占用seq fin包能攜帶data,不論是否攜帶data...
TCP協議簡單講解
tcp transmission control protocol 傳輸控制協議 是一種面向連線的 可靠的 基於位元組流的傳輸層通訊協議。tcp 的連線建立,我們常常稱為三次握手,簡單描述即下。a 您好,我是 a。b 您好 a,我是 b。a 您好 b。三次握手的過程 tcp 的連線關閉,我們常常稱為...
tcp協議的簡單理解
tpc協議屬於傳輸層協議,本篇主要介紹下幾個概念,以及握手和揮手的過程。1.tcp的幾個概念 位碼 即tcp標誌位,有6種提示 syn synchronus,表示建立聯機。ack acknowledgement,確認。push push,傳送。fin finish,結束。rst rest,重置。ur...