把書讀薄(TCP/IP詳解 卷一 第十八章)服務器
ISN:初始序號,能夠看作是一個32比特的計數器,每4ms加1,詳見RFC 793
TCP鏈接是全雙工的,每一個方向都必須單獨關閉
出現場景網絡
服務器在客戶端創建鏈接時恰好斷電。能夠看出客戶端進行了重試,可是重試之間的時間間隔第一次是5.81秒,而第二次間隔是24.00秒。併發
這種超時重試時間間隔對於BSD版的TCP軟件實現來說,是因爲500ms的定時器存在。第一次的間隔通常在5.5-6秒任意時刻超時,而第二次通常穩定在24秒。這是因爲TCP在500ms之內得到系統控制的瞬間,可能系統會優先處理其它中斷,從而第一次計數器減1會發生在0-500ms的任意一個時刻。而每次TCP 500ms定時器被內核調用時都會修正,於是後續穩定tcp
tos 0x10 表示IP數據報內的服務類型,這裏的值爲DNS的udp查詢
鏈接一方發送復位報文來中途釋放鏈接【正常是發送FIN】spa
異常釋放的一端將返回RST報文段,收到的一方將終止鏈接,並通知應用層進行復位,接收方並不對RST報文進行確認。設計
TCP的一端結束髮送後,仍然能接收另外一端發送的數據。排序
應用場景隊列
想僅進行一次排序的操做。流程爲從客戶端讀取用戶輸入的文件,從服務端進行排序,而後客戶端接收排序的結果。對於客戶端來說,當文件傳輸完畢以後不會再發送數據,此時能夠直接關閉,而服務端須要先對數據拍完序,再作迴應,此時客戶端要保持接收數據的能力,這樣就適合使用半關閉(服務端通知客戶端也可使用另外1次TCP鏈接,可是半關閉能夠省掉多餘1次的鏈接過程)進程
鏈接的一端已經關閉或異常終止,可是另外一端確不知道這個狀況。圖片
出現場景
客戶端和服務端正在正常通訊的時候,忽然服務器斷電了,這個時候客戶端並不知道服務器斷電,對於這種狀況,若是服務器當即恢復電源再立馬重啓,當客戶端在服務器重啓以後發送數據時,服務端則回覆復位標識,即TCP的標識位R設置爲1,客戶端收到信息,知曉鏈接終止
相似場景:客戶使用完本身的電腦,直接把電腦電源線拔了,這時服務器並不知道客戶端已經消失,後續客戶端再開機又會創建新的鏈接,這樣致使服務器會存在許多半打開的鏈接
通訊雙方發送的SYN同時到達對方,且一端發送的端口和另外一端要求接收的端口同樣。
出現場景
主機A應用程序使用本地端口7777,與主機B端口8888執行主動打開,主機B應用程序則使用本地端口8888,與主機A端口7777執行主動打開
報文狀態變遷以下
整個過程打開須要4次報文段交換,tcp自己的設計保證,這種場景僅創建了1個鏈接
其它協議族可能創建兩條,好比OSI運輸層
通訊雙方都執行主動關閉。狀態變化以下:
交換的報文段和正常的關閉使用的數目同樣。
RST發生通常是接收端收到的包很明顯和當前鏈接沒有啥關係,這時候就觸發RST包產生
上圖爲客戶端CRASH而後客戶端重連,下圖爲客戶端CRASH而後服務端向客戶端返回數據
此時沒有須要發送的東西,隊列中也沒有未完成的東西須要發送,就生成一個FIN包,發送出去,斷開鏈接
有要發送的東西,好比ack,就去創建鏈接
MSL(Maximum Segment Lifetime)是報文段的最大生存時間。
生存時間是有限的,因爲TCP報文段是以IP數據報在網絡內傳輸,而IP數據報經過TTL的跳數限制,於是報文段被丟棄以前,在網絡內生存時間有限
當TCP執行主動關閉併發回最後一個ACK,該鏈接必須在TIME_WAIT狀態內等待2倍的MSL時間。
緣由:1:TCP主動關閉端發送的ACK若是丟失了,被動關閉端再次重發FIN,這時候的時間等待可以使得TCP主動關閉端發送最後的ACK不會丟失;2下次新的鏈接可能會複用同一個端口,若是因爲網絡延遲,老的數據纔到,會與新數據發生混合,等待2MSL可使得老數據徹底消失
在2MSL時間段以內,定義這個鏈接的插口(客戶端IP和端口,服務端IP和端口),不能再被 被動斷開方使用
若是服務端的鏈接忽然斷開再立馬從新啓動,服務器的這個端口在2MSL時間內客戶端沒法鏈接【這裏客戶端是被動斷開方】;同理若是是客戶端本身斷開,再立馬使用相同的端口,在2MSL時間內去連服務器也是沒法成功的【這裏服務器是被動斷開方】。這種場景客戶端能夠再隨便換一個端口便可,可是服務端的通常應用端口都是固定的,容易形成麻煩
TCP服務器會專門安排一個進程,它永遠處於LISTEN狀態,用來接收客戶端的請求,當請求被接收時,系統中的TCP模塊就會建立一個處於ESTABLISHED狀態的進程
處於LISTEN狀態的進程不能接收數據報文段,處於ESTABLISHED狀態進程不能接收SYN報文段
伯克利TCP實現多鏈接處理規則爲:
TCP接收鏈接是放入鏈接隊列,應用層接收鏈接是從隊列中移除隊列的積壓數與服務器能處理的最大鏈接數沒有關係