TCP/IP協議中的參數說明


  • TCP_NODELAY

對於一個正常的TCP連接連說,TCP數據被封裝在一個I P數據報中,客戶端發送IP報文,服務器端接收IP報文。而一個IP報文的組成部分如下

IP和TCP頭部一共占40個字節,假設客戶端比較變態,每次往服務器端寫一個字節的數據,而tcp立即發送附帶這一個字節IP報文,那么網絡需要傳輸41字節,但是只有實際信息量只有1字節。以前的互聯網帶寬比較低,如果有大量這種信息量比率低的報文在internet上傳輸,會大大影響internet的效率。

所以必須設計一種算法來處理這種情況,客戶端可以設定一個超時時間和報文發送的閥值,在超時時間之內,tcp發送緩存里面的數據長度必須達到報文發送閥值才能夠發送出去。

一種簡單和好的方法就是采用 RFC 896 [Nagle 1984]中所建議的N a g l e算法。

該算法要求一個T C P連接上最多只能有一個未被確認的未完成的小分組,在該分組的確
認到達之前不能發送其他的小分組。相反, T C P收集這些少量的分組,並在確認到來時以一個分組的方式發出去。該算法的優越之處在於它是自適應的:確認到達得越快,數據也就發送得越快。而在希望減少微小分組數目的低速廣域網上,則會發送更少的分組

如果才socket中設置了 TCP_NODELAY 為true,則將關閉 N a g l e 算法。

 

  • SO_REUSEADDR

在正常情況,關閉一個tcp連接的過程是 客戶端主動發送一個fin報文,然后服務器端收到之后發送一個ack報文,然后服務器端發送一個fin報文,然后客戶端在返回一個ack報文。下面一幅圖演示了具體的過程:

可以發現,主動發起關閉的一方(一般是客戶端),tcp連接的狀態會從FIN_WAIT1->FIN_WAIT2->TIME_WAIT->CLOSED

在客戶端主動關閉TCP連接之后,並且服務器端也關閉了連接,發送了FIN報文,這個時候客戶端就變成了TIME_WAIT狀態,這之后就需要發送ack報文給服務器端,服務器端狀態變為CLOSED。

這里面就存在一個問題,雖然客戶端已經關閉TCP連接了,但是還是需要發送一個ack報文給服務器端,這段時間內客戶端TCP連接的狀態一直是TIME_WAIT狀態,而且必須保證ack報文發送給服務器端。所以這個狀態下不能把這個連接重新啟用(一個連接就是一個[本地ip,本地端口,遠程ip,遠程端口],就是說客戶端本地端口不能夠創建新的連接)。

TIME_WAIT狀態要位維持一定的時間,這個時間一般是2倍的報文段最大生存時間M S L(Maximum Segment Lifetime),簡稱2MSL。在這個時間之后,tcp連接狀態變為CLOSED,對應的本地端口上才能夠重新創建連接。為什么要這樣,如果能夠在端口上新創建連接,這個連接上對應的ip報文 服務器端就無法分辨到底是新的連接發送的還是老的連接上的報文信息,畢竟這個時候服務器端TCP通道還可以接收報文。

從上面可以看出,之所以有TIME_WAIT狀態,就是確保客戶端能夠ack 服務器端關閉連接的報文,必須保證服務器端在關閉連接之后,在客戶端才能夠在同樣的端口上創建連接,這樣服務器端才能夠區分報文的發送方。

某些實現和A P I提供了一種避開這個限制的方法。使用插口A P I時,可說明其中的
S O R E U S E A D D R選項。它將讓調用者對處於2 M S L等待的本地端口進行賦值,但我們TCP原則上仍將避免使用仍處於2MSL連接中的端口。

 

  • SO_LINGER

上面描述了TCP報文正常關閉的情況是發送 FIN標志的報文,下面介紹一下TCP頭部的 標志位

U R G 緊急指針( u rgent pointer)有效。
A C K 確認序號有效。
P S H 接收方應該盡快將這個報文段交給應用層。
R S T 重建連接。
S Y N 同步序號用來發起一個連接。
F I N 發端完成發送任務。

在某些情況,客戶端或者服務端可能不想通過兩次交互完成連接的關閉,而是強制關閉連接。這個時候就可以發送RST標志的報文。在這種情況,主動發起連接一方發送RST報文,立即關閉連接。服務器端收到之后RST報文之后,也會關閉連接。這就是我們經常看到的錯誤:“Connection Reset By Peer”

SO_LINGER設置一個具體的時間,如果時間設置為0,那么當我們關閉 連接的時候,就會像上面我們描述的那樣。如果設置時間為timeout,那么在timeout這段時間內,如果數據沒有發送完成,會強制發送一個RST報文,關閉連接,如果在timeout時間,報文發送完成,就發送一個FIN報文,正常關閉連接。

 

  • SO_TIMEOUT

這個設置的是超時時間,客戶端和服務器端表現的會不一樣的。可以設置一個具體的timeout值

對於客戶端,在發起連接的時候,如果在timeout時間內沒有連接上,就產生異常

對於服務器,在監聽客戶端連接的時候,也就是accept方法,如果超過了指定時間,就異常。

客戶端和服務器端 read數據的時候,如果超過了timeout時間,也會發生異常。

 

  • SO_KEEPALIVE

在某一些極端情況下,客戶端和服務器端建立了tcp連接,但是客戶端和服務器端都不發送數據,這樣就導致了這一對連接就閑置在那里或者僵死了。一般情況下,我們可以通過上層應用檢測這種情況,一旦在一段時間內客戶端沒有發送數據,服務器端就關閉連接。

在tcp協議里面,定義了保活定時器,tcp實現會定時的去探測對方端口是否是有效性的,一般情況下,會發送一個 tcp probe(tcp 探針),這個時間是2兩個小時。

可能存在以下四種情況

1) 客戶主機依然正常運行,並從服務器可達。客戶的T C P響應正常,而服務器也知道對方是正常工作的。服務器在兩小時以后將保活定時器復位。如果在兩個小時定時器到時間之前有應用程序的通信量通過此連接,則定時器在交換數據后的未來2小時再復位。

2) 客戶主機已經崩潰,並且關閉或者正在重新啟動。在任何一種情況下,客戶的T C P都沒有響應。服務器將不能夠收到對探查的響應,並在7 5秒后超時。服務器總共發送1 0個這樣的探查,每個間隔7 5秒。如果服務器沒有收到一個響應,它就認為客戶主機已經關閉並終止連接。

3) 客戶主機崩潰並已經重新啟動。這時服務器將收到一個對其保活探查的響應,但是這個響應是一個復位(RST),使得服務器終止這個連接。

4) 客戶主機正常運行,但是從服務器不可達。這與狀態2相同。

由於這個時間是2個小時,並且對上層應用透明,比如如果出現3這種情況,應用對socket操作,就會產生異常。所以一般情況下會設置為fasle ,來關閉這個保活定時器。由上層應用來負責連接管理。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM