TCP協議與其它協議之間的關係:linux
+------+ +-----+ +-----+ +-----+ |Telnet| | FTP | |Voice| ... | | Application Level +------+ +-----+ +-----+ +-----+ | | | | +-----+ +-----+ +-----+ | TCP | | RTP | ... | | Host Level +-----+ +-----+ +-----+ | | | +-------------------------------+ | Internet Protocol & ICMP | Gateway Level +-------------------------------+ | +---------------------------+ | Local Network Protocol | Network Level +---------------------------+
TCP的流控制是經過在接收者發往發送者的ACK中TCP首部的window字段(接收窗口長度)來實現的:nginx
TCP provides a means for the receiver to govern the amount of data sent by the sender. This is achieved by returning a "window" with every ACK indicating a range of acceptable sequence numbers beyond the last segment successfully received. The window indicates an allowed number of octets that the sender may transmit before receiving further permission.
TCP具備超時重發的機制,若是在指定時間內沒有接收到相應的ACK,那麼相應的Segment將會從新發送。面試
能夠同時打開多個SOCKET去監聽同一個PORT, 那麼TCP將首先匹配到指定外部SOCKET地址的TCB,而後再去匹配不指定外部SOCKET地址的TCB。編程
icmp能夠用於獲取另外一臺機器的時間,發送端在「發送時間戳」字段填入發送的時間,而接收端須要在「接收時間戳」字段寫入接收到的時間並再次發回給發送端,這樣子一來發送端就能夠計算出從往返延遲了。另外RFC1307還描述了一種毫秒級的時間同步協議。centos
一個鏈接同時使用sourceIP destIP sourcePort destPort來惟一肯定 。網絡
爲何TCP須要3次握手而不是2次:socket
第一次在面試題裏面看到這個問題,根RFC793上的說法,TCP其於IP(Internet Protocol)協議,IP協議是不可靠的,創建一個100%可靠的鏈接顯然不可能。固然,若是鏈接足夠可靠,那咱們無須進行這個過程,或者咱們能夠將握手的次數增長到4次或者5次以獲得一個更加穩定的鏈接),3次鏈接則是這樣子的一個折中。能夠避免大部分錯誤的狀況,同時節省創建鏈接的消耗。ide
從另外一個方面來講,讓鏈接雙方都相互「知道」彼此的ISN,那麼至少進行3次握手,兩次學習到其中一方的ISN。學習
由於握手過程當中發送的SYN和ACK可能會遲到或者丟失,因此,在不穩定的網絡環境中,兩次握手是不恰當的,好比下面的過程,TCP發出ACK以後立刻進入ESTABLISHED狀態,並通知上層的應用程序,但步驟2中的ACK極可能會丟失。若是某個時候網絡環境很糟糕,上層的應用則獲得大量無效的鏈接,這是不恰當的。spa
TCP A TCP B CLOSED LISTEN 1: (SYN_SENT) ---(SEQ=100,CTL=SYN) --> (SYN_RECEIVED) 2: (ESTABLISHED) <--(SEQ=300,ACK=101,CTL=ACK) -- (ESTABLISHED)
POSSIBILITY 1
TCP A TCP B
CLOSED LISTEN
1: (SYN_SENT) ---(SEQ=100,CTL=SYN) ... LISTEN
2: (SYN_SENT) ---(SEQ=110,CTL=SYN) ... LISTEN
3: ---(SEQ=100,CTL=SYN) --> (SYC_RECEIVED)
4: (ESTABLISHED) <--(SEQ=200,ACK=101,CTL=ACK) --- (ESTABLISHED)
5: ---(SEQ=110,CTL=SYN) --> (???)
POSSIBILITY 2
一些控制packet的segment length==1
Usually, TCP packets with a len of 1 are control packets (ACK,SYN,FIN,RST)
TCP鏈接斷開的過程也比較麻煩,有四次握手的說法,但這種說法能夠說不是很準確。
TCP A
CLOSE_WAIT_1 ---(SEQ=300,ACK=100,CTL=<FIN,ACK>) --> FIN_WAIT
CLOSE_WAIT_2 <--(SEQ=100,ACK=301,CTL=<ACK>) --- FIN_WAIT
TIME_WAIT <--(SEQ=xxx,ACK=301,CTL=<FIN,ACK>) --- LAST_ACK(Close)
TIME_WAIT ---(SEQ=301,ACK=101,CTL=<ACK>) --> CLOSED
2MSL(TIME_WAIT)
CLOSED
發送方接收到ACK時,在重發隊列中全部的SEGMENT,若是SEG.SEQ + SEG.LEN <= ACK.SEQ,則這個SEGMENT被接收者確認(Acknowledged),並能夠從隊列中移出。
今天同事作技術交流的時候帶回來了一些問題:
1、三次握手完成以前是否須要accept操做,從上面的握手過程能夠知道,只有三次握手完成以後,網絡棧纔會認爲這個東西是正確的。而後纔會交給應用進程去處理。
2、主進程和子進程之間共享socket文件描述符時候,好比nginx,三次握手的時候(中間過程),netstat的時候,這個鏈接是的進程號是誰的?其實這個現象是不肯定的,好比centos平臺上面,netstat的時候,進程號部分爲-,即不知道這個鏈接歸那個進程號全部。
3、linux平臺上面只要拿到文件描述符就能夠對socket進行accept,好比nginx的二進制文件升級的時候,用的就是這個特性。
其實這些東西都仍是些linux 編程的東西,仍是回去好好搞LINUX內核和LINUX平臺上的編程?FUCK