1. so_linger/ so_reuseaddr
tcp正常的關閉過程如下(四次握手過程):
(fin_wait_1) a ---fin---> b(close_wait)
(fin_wait_2) a <--ack-- b(close_wait)
(time_wait)a <--fin---- b(last_ack)
(time_wait)a ---ack-> b(closed)
a端首先傳送乙個fin請求給b端,要求關閉,傳送後a段的tcp狀態變更為fin_wait_1,接收到fin請求後b端的tcp狀態變更為close_wait
b接收到ack請求後,b回乙個ack給a端,確認接收到的fin請求,接收到ack請求後,a端的tcp狀態變更為為fin_wait_2。
b端再傳送乙個fin請求給a端,與連線過程的3次握手過程不一樣,這個fin請求之所以並不是與上乙個請求一起傳送,之所以如此處理,是因為tcp是雙通道的,允許在傳送ack請求後,並不馬上發fin請求,即只關閉a到b端的資料流,仍然允許b端到a端的資料流。這個ack請求傳送之後,b端的tcp狀態變更為last_ack,a端的狀態變更為time_wait。
a端接收到b端的fin請求後,再回b端乙個ack資訊,對上乙個fin請求進行確認,到此時b端狀態變更為closed,socket可以關閉。
除了如上正常的關閉(優雅關閉)之外,tcp還提供了另外一種非優雅的關閉方式rst(reset)
(closed) a ---rst--> b (closed)
a端傳送rst狀態之後,tcp進入closed狀態,b端接收到rst後,也即可進入closed狀態。
在第一種關閉方式上(優雅關閉),非常遺憾,a端在最後傳送乙個ack請求後,並不能馬上將該socket**,因為a並不能確定b一定能夠接收到這個ack請求,因此a端必須對這個socket維持time_wait狀態2msl(msl=max segment lifetime,取決於作業系統和tcp實現,該值為30秒、60秒或2分鐘)。如果a端是客戶端,這並不會成為問題,但如果a端是服務端,那就很危險了,如果連線的socket非常多,而又維持如此多的time_wait狀態的話,那麼有可能會將socket耗盡(報too many open file)。
服務端為了解決這個問題,可選擇的方式有三種:
一般我們當然最好是選擇第一種方式,實在沒有辦法的時候,我們可以使用so_linger選擇第二種方式,使用so_reuseaddr選擇第三種方式
第乙個on表示是否使用so_linger選項,linger(以秒為單位)表示在發rst之前會等待多久,因為一旦傳送rst,還在緩衝區中還沒有傳送出去的資料就會直接丟棄
值得注意的是socket.setresuseaddress(true)方法必須在socket還沒有繫結到乙個本地埠之前呼叫,否則執行socket.setresuseaddress(true)方法無效。因此必須按照以下方式建立socket物件,然後再連線遠端伺服器:
2.tcp_nodelay
對於互動型的應用(譬如telnet),經常存在的情況是客戶端和服務端之間需要頻繁地進行一些小資料交換,譬如telnet可能每敲乙個鍵盤都需要將資料傳送到服務端。為了避免這種情況會產生大量小資料報,提出了nagle演算法。nagle演算法要求每次在傳送端最後只有乙個未被確認的包,因此上乙個包傳送出去還沒有接收到響應之前,要求傳送的包回先放在緩衝區,接收到響應之後,會將緩衝區中的包合併成乙個包傳送出去(可以看到,響應回地越快,傳送出去的資料也會越快)。
需要注意的是,由nagle演算法要求只能有乙個未被確認的包,因此視窗引數會失效,在大資料量傳送的情況下會使網路吞吐量下降,因此對於大資料量的互動,應該關閉nagle演算法,nagle演算法比較適合小資料量頻繁交換的情景。我們可以使用tcp_nodelay關閉nagle演算法。
3.so_keepalive
在乙個tcp連線建立之後,我們會很奇怪地發現,預設情況下,如果一端異常退出(譬如網路中斷後一端退出,使地關閉請求另一端無法接收到),tcp的另一端並不能獲得這種情況,仍然會保持乙個半關閉的連線,對於服務端,大量半關閉的連線將會是非常致命的。so_keepalive提供了一種手段讓tcp的一端(通常服務提供者端)可以檢測到這種情況。如果我們設定了so_keepalive,tcp在距離上一次tcp包互動2個小時(取決於作業系統和tcp實現,規範建議不低於2小時)後,會傳送乙個探測包給另一端,如果接收不到響應,則在75秒後重新傳送,連續10次仍然沒有響應,則認為對方已經關閉,系統會將該連線關閉。一般情況下,如果對方已經關閉,則對方的tcp層會回rst響應回來,這種情況下,同樣會將連線關閉。
4. so_timeout選項
1) 設定該選項:public void setsotimeout(int milliseconds) throws socketexception
2) 讀取該選項:public int getsotimeout() throws socketexception
3) 當通過socket的輸入流讀資料時,如果還沒有資料,就會等待。socket類的so_timeout選項用於設定接收資料的等待超時時間,單位為毫秒,它的預設值為0,表示會無限等待,永遠不會超時。
4) socket的setsotimeout()方法必須在接收資料之前執行才有效。此外,當輸入流的read()方法丟擲sockettimeoutexception後,socket仍然是連線的,可以嘗試再次讀取資料。
5. so_rcvbuf選項
1) 設定該選項:public void setreceivebuffersize(int size) throws socketexception
2) 讀取該選項:public int getreceivebuffersize() throws socketexception
3) so_rcvbuf表示socket的用於輸入資料的緩衝區的大小。
4) 如果底層socket不支援so_rcvbuf選項,那麼setreceivebuffersize()方法會丟擲socketexception。
6. so_sndbuf選項
1) 設定該選項:public void setsendbuffersize(int size) throws socketexception
2) 讀取該選項:public int getsendbuffersize() throws socketexception
3) so_sndbuf表示socket的用於輸出資料的緩衝區的大小。
4) 如果底層socket不支援so_sndbuf選項,setsendbuffersize()方法會丟擲socketexception。
7. 服務型別選項
1) ip規定了四種服務型別,用來定性的描述服務的質量:
l 低成本:傳送成本低。
l 高可靠性:保證把資料可靠的送達目的地。
l 最高吞吐量:一次可以接收或傳送大批量的資料。
l 最小延遲:傳輸資料的速度快,把資料快速送達目的地。
2) 這四種服務型別還可以進行組合,例如,可以同時要求獲得高可靠性和最小延遲。socket類中提供了設定和讀取服務型別的方法:
l 設定服務型別:public void settrafficclass(int trafficclass) throws socketexception
l 讀取服務型別:public int gettrafficclass() throws socketexception
3) socket類用四個整數表示服務型別:
l 低成本:0x02 (二進位制的倒數第二位為1)
l 高可靠性:0x04(二進位制的倒數第三位為1)
l 最高吞吐量:0x08(二進位制的倒數第四位為1)
l 最小延遲:0x10(二進位制的倒數第五位為1)
10. 設定連線時間、延遲和頻寬的相對重要性
public void setperformancepreferences(int connectiontime,int latency,int bandwidth)
以上方法的三個引數表示網路傳輸資料的三項指標:
n 引數connectiontime:表示用最少時間建立連線。
n 引數latency:表示最小延遲。
n 引數bandwidth:表示最高頻寬。
setperformancepreferences()方法用來設定這三項指標之間的相對重要性。可以為這些引數賦予任意的整數,這些整數之間的相對大小就決定了相應引數的相對重要性。例如,如果引數connectiontime為2,引數latency為1,而引數bandwidth為3,就表示最高頻寬最重要,其次是最少連線時間,最後是最小延遲。
adb logcat選項解析
adb logcat 命令格式 adb logcat 選項 過濾項 其中 選項 和 過濾項 在 中括號 中,說明這是可選的 s 選項 設定輸出日誌的標籤,只顯示該標籤的日誌 如 我們想要輸出 system.out 標籤的資訊,就可以使用adb logcat s system.out 命令 f 選項 ...
Tcp ip 報文解析
在編寫網路程式時,常使用tcp協議。那麼乙個tcp包到底由哪些東西構成的呢?其實乙個tcp包,首先需要通過ip協議承載,而ip報文,又需要通過乙太網傳送。下面我們來看看幾種協議頭的構成 一 ethernet頭 以太幀分好幾種型別,常見的以太幀為ethernet ii 下面就是乙個典型的etherne...
TCP IP詳解 TCP首部選項中時間戳選項
一 簡介 tcp時間戳選項會在tcp包頭增加12個位元組,以一種比重發超時更精確的方法來啟用對rtt 的計算。二 作用 1 tcp時間戳位於tcp選項中,kind 8 lenth 10 data由timestamp和timestamp echo兩個值組成,各4個位元組的長度。2 tcp時間戳理論作用...