??TCP/IP(Transmission Control Protocol/Internet Protocol) 即傳輸控制協(xié)議/網(wǎng)間協(xié)議,是一個(gè)工業(yè)標(biāo)準(zhǔn)的協(xié)議集,它是為廣域網(wǎng)(WAN)設(shè)計(jì)的。它是由ARPANET網(wǎng)的研究機(jī)構(gòu)發(fā)展起來的。
??TCP/IP的標(biāo)準(zhǔn)在一系列稱為RF [1] C的文檔中公布。文檔由技術(shù)專家、特別工作組、或RFC編輯修訂。公布一個(gè)文檔時(shí),該文檔被賦予一個(gè)RFC編號(hào),如RFC959(FTP的說明文檔)、RFC793(TCP的說明文檔)、RFC791(IP的說明文檔)等。最初的RFC一直保留而從來不會(huì)被更新, [1] 如果修改了該文檔,則該文檔又以一個(gè)新號(hào)碼公布。因此,重要的是要確認(rèn)你擁有了關(guān)于某個(gè)專題的最新RFC文檔。通常在RFC的開頭部分,有相關(guān)RFC的更新(update)、排錯(cuò)(errata)、作廢(obsolete)信息,提示讀者信息的時(shí)效性。
首部格式
TCP的首部格式圖如下所示:

---Source Port是源端口,16位。
---Destination Port是目的端口,16位。
---Sequence Number是發(fā)送數(shù)據(jù)包中的第一個(gè)字節(jié)的序列號(hào),32位。
---Acknowledgment Number是確認(rèn)序列號(hào),32位。
---Data Offset是數(shù)據(jù)偏移,4位,該字段的值是TCP首部(包括選項(xiàng))長(zhǎng)度除以4。 [1]
---標(biāo)志位: 6位,URG表示Urgent Pointer字段有意義:
ACK表示Acknowledgment Number字段有意義
PSH表示Push功能,RST表示復(fù)位TCP連接
SYN表示SYN報(bào)文(在建立TCP連接的時(shí)候使用)
FIN表示沒有數(shù)據(jù)需要發(fā)送了(在關(guān)閉TCP連接的時(shí)候使用)
Window表示接收緩沖區(qū)的空閑空間,16位,用來告訴TCP連接對(duì)端自己能夠接收的最大數(shù)據(jù)長(zhǎng)度。
---Checksum是校驗(yàn)和,16位。
---Urgent Pointers是緊急指針,16位,只有URG標(biāo)志位被設(shè)置時(shí)該字段才有意義,表示緊急數(shù)據(jù)相對(duì)序列號(hào)(Sequence Number字段的值)的偏移。
連接建立
TCP是因特網(wǎng)中的傳輸層協(xié)議,使用三次握手協(xié)議建立連接。當(dāng)主動(dòng)方發(fā)出SYN連接請(qǐng)求后,等待對(duì)方回答
SYN+ACK [1] ,并最終對(duì)對(duì)方的 SYN 執(zhí)行 ACK 確認(rèn)。這種建立連接的方法可以防止產(chǎn)生錯(cuò)誤的連接,TCP使用的流量控制協(xié)議是可變大小的滑動(dòng)窗口協(xié)議。 [1]
TCP三次握手的過程如下:

客戶端發(fā)送SYN(SEQ=x)報(bào)文給服務(wù)器端,進(jìn)入SYN_SEND狀態(tài)。
服務(wù)器端收到SYN報(bào)文,回應(yīng)一個(gè)SYN (SEQ=y)ACK(ACK=x+1)報(bào)文,進(jìn)入SYN_RECV狀態(tài)。
客戶端收到服務(wù)器端的SYN報(bào)文,回應(yīng)一個(gè)ACK(ACK=y+1)報(bào)文,進(jìn)入Established狀態(tài)。
三次握手完成,TCP客戶端和服務(wù)器端成功地建立連接,可以開始傳輸數(shù)據(jù)了。
連接終止

建立一個(gè)連接需要三次握手,而終止一個(gè)連接要經(jīng)過四次握手,這是由TCP的半關(guān)閉(half-close)造成的。具體過程如下圖所示。 [1]
(1) 某個(gè)應(yīng)用進(jìn)程首先調(diào)用close,稱該端執(zhí)行“主動(dòng)關(guān)閉”(active close)。該端的TCP于是發(fā)送一個(gè)FIN分節(jié),表示數(shù)據(jù)發(fā)送完畢。
(2) 接收到這個(gè)FIN的對(duì)端執(zhí)行 “被動(dòng)關(guān)閉”(passive close),這個(gè)FIN由TCP確認(rèn)。
注意:FIN的接收也作為一個(gè)文件結(jié)束符(end-of-file)傳遞給接收端應(yīng)用進(jìn)程,放在已排隊(duì)等候該應(yīng)用進(jìn)程接收的任何其他數(shù)據(jù)之后,因?yàn)?,F(xiàn)IN的接收意味著接收端應(yīng)用進(jìn)程在相應(yīng)連接上再無額外數(shù)據(jù)可接收。
(3) 一段時(shí)間后,接收到這個(gè)文件結(jié)束符的應(yīng)用進(jìn)程將調(diào)用close關(guān)閉它的套接字。這導(dǎo)致它的TCP也發(fā)送一個(gè)FIN。
(4) 接收這個(gè)最終FIN的原發(fā)送端TCP(即執(zhí)行主動(dòng)關(guān)閉的那一端)確認(rèn)這個(gè)FIN。 [1]
既然每個(gè)方向都需要一個(gè)FIN和一個(gè)ACK,因此通常需要4個(gè)分節(jié)。
注意:
(1) “通常”是指,某些情況下,步驟1的FIN隨數(shù)據(jù)一起發(fā)送,另外,步驟2和步驟3發(fā)送的分節(jié)都出自執(zhí)行被動(dòng)關(guān)閉那一端,有可能被合并成一個(gè)分節(jié)。 [2]
(2) 在步驟2與步驟3之間,從執(zhí)行被動(dòng)關(guān)閉一端到執(zhí)行主動(dòng)關(guān)閉一端流動(dòng)數(shù)據(jù)是可能的,這稱為“半關(guān)閉”(half-close)。
(3) 當(dāng)一個(gè)Unix進(jìn)程無論自愿地(調(diào)用exit或從main函數(shù)返回)還是非自愿地(收到一個(gè)終止本進(jìn)程的信號(hào))終止時(shí),所有打開的描述符都被關(guān)閉,這也導(dǎo)致仍然打開的任何TCP連接上也發(fā)出一個(gè)FIN。
無論是客戶還是服務(wù)器,任何一端都可以執(zhí)行主動(dòng)關(guān)閉。通常情況是,客戶執(zhí)行主動(dòng)關(guān)閉,但是某些協(xié)議,例如,HTTP/1.0卻由服務(wù)器執(zhí)行主動(dòng)關(guān)閉。 [2]