逝者如斯夫

          靜而思之

          導(dǎo)航

          留言簿(62)

          隨筆分類

          最新隨筆

          搜索

          •  

          最新評論

          閱讀排行榜

          TCP連接的過程

          編寫:Leaf Zhou
          EMAIL:leaf_zhou_8@hotmail.com

          TCP是英文Transport Control Protocol的縮寫。從字面理解,就是傳輸控制協(xié)議。因此,TCP是一種控制協(xié)議,他本身不能用來傳輸數(shù)據(jù),它需要通過網(wǎng)絡(luò)層的IP協(xié)議來進行實際數(shù)據(jù)的傳輸。這也就是我們常常看到,TCP/IP和TCP/UDP總是同時出現(xiàn)的原因。因此,也可以理解為TCP是很多的不同的協(xié)議組成,實際上是一個協(xié)議組。提供可靠的主機到主機層數(shù)據(jù)傳輸控制協(xié)議。這里要先強調(diào)一下,傳輸控制協(xié)議是OSI網(wǎng)絡(luò)的第四層的叫法,TCP傳輸控制協(xié)議是TCP/IP傳輸?shù)?個基本協(xié)議的一種。TCP是一種可靠的面向連接的傳送服務(wù)。它在

          一、TCP概述
          TCP是英文Transport Control Protocol的縮寫。從字面理解,就是傳輸控制協(xié)議。因此,TCP是一種控制協(xié)議,他本身不能用來傳輸數(shù)據(jù),它需要通過網(wǎng)絡(luò)層的IP協(xié)議來進行實際數(shù)據(jù)的傳輸。這也就是我們常常看到,TCP/IP和TCP/UDP總是同時出現(xiàn)的原因。因此,也可以理解為TCP是很多的不同的協(xié)議組成,實際上是一個協(xié)議組。提供可靠的主機到主機層數(shù)據(jù)傳輸控制協(xié)議。這里要先強調(diào)一下,傳輸控制協(xié)議是OSI網(wǎng)絡(luò)的第四層的叫法,TCP傳輸控制協(xié)議是TCP/IP傳輸?shù)?個基本協(xié)議的一種。TCP是一種可靠的面向連接的傳送服務(wù)。它在傳送數(shù)據(jù)時是分段進行的,主機交換數(shù)據(jù)必須先建立一個會話。它用比特流通信,即數(shù)據(jù)被作為無結(jié)構(gòu)的字節(jié)流進行傳輸,沒有數(shù)據(jù)邊界。通過每個TCP傳輸?shù)淖侄沃付樞蛱枺垣@得可靠性。是在OSI參考模型中的第四層,TCP是使用IP的網(wǎng)間互聯(lián)功能而提供可靠的數(shù)據(jù)傳輸,IP不停的把報文放到網(wǎng)絡(luò)上,而TCP是負(fù)責(zé)確信報文到達。在協(xié)同IP的操作中TCP負(fù)責(zé):握手過程、報文管理、流量控制、錯誤檢測和處理(控制),可以根據(jù)一定的編號順序?qū)Ψ钦m樞虻膱笪慕o予從新排列順序。關(guān)于TCP的RFC文檔有RFC793、RFC791、RFC1700。

          二、TCP連接的建立
          建立一個TCP連接,需要下面的步驟:
          (1)服務(wù)器端通過listen來準(zhǔn)備接受外來的連接,稱為被動打開(passive open)。
          (2) 客戶端通過connect進行連接服務(wù)器,稱為主動打開(active open)。在這個操作中,客戶端需要發(fā)送一個同步數(shù)據(jù)報(SYN),用來通知服務(wù)器端開始發(fā)送數(shù)據(jù)的初始序列號。通常情況下,同步數(shù)據(jù)報不攜帶數(shù)據(jù),它只包含一個IP頭部、一個TCP頭部和本次通信所使用的TCP的選項。
          (3)服務(wù)器端必須對客戶端發(fā)來的同步數(shù)據(jù)報SYN進行確認(rèn),同時自己也要發(fā)送一個同步數(shù)據(jù)報(SYN),它包含客戶端發(fā)送數(shù)據(jù)的初始序列號。服務(wù)器端對在同一連接中發(fā)送的數(shù)據(jù)初始序號和對客戶端發(fā)送的確認(rèn)信息(ACK),都放在一個數(shù)據(jù)報中,一起發(fā)送給客戶端。
          (4)客戶端也必須發(fā)送確認(rèn)服務(wù)器端的同步數(shù)據(jù)報(SYN)。
          由上面的步驟來看,建立一個TCP連接,至少需要服務(wù)器端和客戶端進行三個分組數(shù)據(jù)的交換,因此,稱之為TCP的三路握手(three-way handshake)。

          ????????????客戶端???????????????????????????服務(wù)器端
          ????????????connect()????????????????????????accept()
          ????????????????????? --->?SYN?S?----->???
          ??????????????????????<---?SYN?C
          , ACK?S+ 1 ?<---??????
          ??????????????????????--->?ACK?C+
          1 ?----->

          第一次進行分組數(shù)據(jù)交換的過程中,分組數(shù)據(jù)中可能包含著本次通信中可能的TCP選項。這些選項有:
          (1) 最大分組(MSS)選項。TCP發(fā)送的SYN中帶有這個選項,用來告訴對方它的最大分組數(shù)據(jù)的大小MSS(Maximum Segment Size),即它能接收的每個TCP分組數(shù)據(jù)中的最大數(shù)據(jù)量。這個選項可以通過TCP_MAXSEG套接口選項獲取與設(shè)置這個TCP選項。
          (2) 窗口大小選項。這是TCP能提供流量控制的主要手段。TCP連接的每一方都有固定大小的緩沖空間,TCP的接收端只允許另一端發(fā)送接收端緩沖區(qū)所能接納的數(shù)據(jù)。這將防止較快主機致使較慢主機的緩沖區(qū)溢出。TCP雙方能夠通知對方的最大窗口大小是64K(65535 bytes),因為TCP頭部相應(yīng)的標(biāo)識字段值只用了16位來表示。每個套接口都有一個發(fā)送緩沖區(qū)和一個接收緩沖區(qū),接收緩沖區(qū)被TCP和UDP用來將接收到的數(shù)據(jù)一直保存到由應(yīng)用進程來讀取。對于TCP,TCP通告另一端的窗口大小。 TCP套接口接收緩沖區(qū)不可能溢出,因為對方不允許發(fā)出超過所通告窗口大小的數(shù)據(jù)。這就是TCP的流量控制,如果對方無視窗口大小而發(fā)出了超過窗口大小的數(shù)據(jù),則接收方TCP將丟棄它;而對于UDP,當(dāng)套接口接收緩沖區(qū)放不下接收到的數(shù)據(jù)報時,此數(shù)據(jù)報就被丟棄。UDP是沒有流量控制的,快的發(fā)送者可以很容易地就淹沒慢的接收者,導(dǎo)致接收方的UDP丟棄數(shù)據(jù)報,使數(shù)據(jù)發(fā)生丟失。
          (3)時間戳選項。時間戳選項使發(fā)送方在每個報文段中放置一個時間戳值。接收方在確認(rèn)中返回這個數(shù)值,從而允許發(fā)送方為每一個收到的ACK計算RTT。

          三、TCP連接的終止
          終止TCP連接
          TCP用三個分組數(shù)據(jù)建立一個連接,但要終止一個連接則通常需要需要四個分組數(shù)據(jù)。過程如下:
          (1)先調(diào)用close的進程,稱為主動關(guān)閉(active close)。這一端的TCP先發(fā)送一個FIN分組數(shù)據(jù),告訴對方,數(shù)據(jù)發(fā)送完畢。
          (2)接收到FIN分組數(shù)據(jù)的一端執(zhí)行被動關(guān)閉(passive close),同時,發(fā)送對這個FIN的確認(rèn)ACK分組數(shù)據(jù)給對方。確認(rèn)序號為收到的序號加1。FIN分組數(shù)據(jù)的接收意味著在當(dāng)前的連接上,再也不會收到額外的數(shù)據(jù)。
          (3)接收到FIN分組數(shù)據(jù)的一端的應(yīng)用進程,將調(diào)用close關(guān)閉自己的套接口,同時TCP 會發(fā)送一個FIN分組數(shù)據(jù)給另一端。
          (4)收到這個FIN的分組數(shù)據(jù),即執(zhí)行主動關(guān)閉的一端對這個FIN分組數(shù)據(jù)進行確認(rèn)。發(fā)回確認(rèn)ACK分組數(shù)據(jù),并將確認(rèn)序號設(shè)置為收到序號加1

          在這個過程中,執(zhí)行被動關(guān)閉的一方可以把確認(rèn)對方FIN分組數(shù)據(jù)的ACK分組數(shù)據(jù)和自己要發(fā)送的FIN分組數(shù)據(jù)可以放到一個分組數(shù)據(jù)中。TCP的連接終止的過程如下:

          ????????????客戶端???????????????????????????服務(wù)器端
          ????????????close()??????????????????????????close()
          ??????????????????????--->?FIN?S?----->???
          ??????????????????????<---?ACK?S+
          1 ?<---??????
          ??????????????????????<---?FIN?C???<---
          ??????????????????????--->?FIN?C+
          1 ?--->

          四、TCP連的狀態(tài)?????????????????
          TCP的連接的建立和終止,基本上已經(jīng)清楚了,那么在這個過程中,是如何知道這個連接正處在什么狀態(tài)呢?方法當(dāng)然是有的,我們先運行如下命令,看看返回的結(jié)果:

          [root@linux81?leaf]#?netstat?-an
          Active?Internet?connections?(servers?and?established)
          Proto?Recv-Q?Send-Q?Local?Address???????????Foreign?Address?????????State????
          tcp????????
          0??????0?0.0.0.0:3306????????????0.0.0.0:*???????????????LISTEN????
          tcp????????
          0??????0?0.0.0.0:139?????????????0.0.0.0:*???????????????LISTEN????
          tcp????????
          0??????0?0.0.0.0:21??????????????0.0.0.0:*???????????????LISTEN????
          tcp????????
          0??????0?0.0.0.0:22??????????????0.0.0.0:*???????????????LISTEN????
          tcp????????
          0??????0?0.0.0.0:23??????????????0.0.0.0:*???????????????LISTEN????
          tcp????????
          0??????0?192.168.253.81:139??????192.168.253.35:1201?????ESTABLISHED
          tcp????????
          0????272?192.168.253.81:22???????192.168.253.59:1776?????ESTABLISHED
          udp????????
          0??????0?192.168.253.81:137??????0.0.0.0:*?????????????????????????
          udp????????
          0??????0?0.0.0.0:137?????????????0.0.0.0:*?????????????????????????
          udp????????
          0??????0?192.168.253.81:138??????0.0.0.0:*?????????????????????????
          udp????????
          0??????0?0.0.0.0:138?????????????0.0.0.0:*?????????????????????????
          udp????????
          0??????0?127.0.0.1:36260?????????0.0.0.0:*??????????

          在上面的返回結(jié)果中,State一列,就是說明連接的當(dāng)前狀態(tài)。
          TCP的連接狀態(tài)有:
          (01)CLOSED??
          (02)LISTEN??? 被動打開
          (03)SYN_RCVD??
          (04)SYN_SEND
          (05)ESTABLISHED?? 數(shù)據(jù)傳送狀態(tài)
          (06)CLOSE_WAIT
          (07)LAST_ACK?? 被動關(guān)閉
          (08)FIN_WAIT_1
          (09)FIN_WAIT_2
          (10)CLOSING
          (11)TIME_WAIT

          TCP連接狀態(tài)轉(zhuǎn)換示意圖如下所示:

          ??????????????????????????????+---------+?---------\??????active?OPEN
          ??????????????????????????????|??CLOSED?|????????????\????-----------
          ??????????????????????????????+---------+<---------\???\???create?TCB
          ????????????????????????????????|?????^??????????????\???\??snd?SYN??
          ???????????????????passive?OPEN?|?????|???CLOSE????????\???\?????????
          ???????????????????------------?|?????|?----------???????\???\???????
          ????????????????????create?TCB??|?????|?delete?TCB?????????\???\?????
          ????????????????????????????????V?????|??????????????????????\???\???
          ??????????????????????????????+---------+????????????CLOSE????|????\?
          ??????????????????????????????|??LISTEN?|??????????----------?|?????|
          ??????????????????????????????+---------+??????????delete?TCB?|?????|
          ???????????????????rcv?SYN??????|?????|?????SEND??????????????|?????|
          ??????????????????-----------???|?????|????-------????????????|?????V
          +---------+??????snd?SYN
          ,ACK??/???????\???snd?SYN??????????+---------+
          |?????????|<-----------------???????????------------------>|?????????|
          |???SYN???|????????????????????rcv?SYN?????????????????????|???SYN???|
          |???RCVD??|<-----------------------------------------------|???SENT??|
          |?????????|????????????????????snd?ACK?????????????????????|?????????|
          |?????????|------------------???????????-------------------|?????????|
          +---------+???rcv?ACK?of?SYN??\???????/??rcv?SYN
          ,ACK???????+---------+
          ???|???????????--------------???|?????|???-----------????????????????
          ???|??????????????????x?????????|?????|?????snd?ACK??????????????????
          ???|????????????????????????????V?????V??????????????????????????????
          ???|??CLOSE???????????????????+---------+????????????????????????????
          ???|?-------??????????????????|??ESTAB??|????????????????????????????
          ???|?snd?FIN??????????????????+---------+????????????????????????????
          ???|???????????????????CLOSE????|?????|????rcv?FIN???????????????????
          ???V??????????????????-------???|?????|????-------???????????????????
          +---------+??????????snd?FIN??/???????\???snd?ACK??????????+---------+
          |??FIN????|<-----------------???????????------------------>|??CLOSE??|
          |?WAIT-
          1??|------------------??????????????????????????????|???WAIT??|
          +---------+??????????rcv?FIN??\????????????????????????????+---------+
          ???|?rcv?ACK?of?FIN???-------???|????????????????????????????CLOSE??|
          ???|?--------------???snd?ACK???|???????????????????????????-------?|
          ???V????????x???????????????????V???????????????????????????snd?FIN?V
          +---------+??????????????????+---------+???????????????????+---------+
          |FINWAIT-
          2|??????????????????|?CLOSING?|???????????????????|?LAST-ACK|
          +---------+??????????????????+---------+???????????????????+---------+
          ???|????????????????rcv?ACK?of?FIN?|?????????????????rcv?ACK?of?FIN?|
          ???|??rcv?FIN???????--------------?|????Timeout
          =2MSL?--------------?|
          ???|??-------??????????????x???????V????------------????????x???????V
          ????\?snd?ACK?????????????????+---------+delete?TCB?????????+---------+
          ?????------------------------>|TIME?WAIT|------------------>|?CLOSED??|
          ??????????????????????????????+---------+???????????????????+---------+

          ????????????????????? TCP Connection State Diagram

          從上面的圖表中,可以做出如下總結(jié):
          服務(wù)器端的正常狀態(tài)轉(zhuǎn)換過程如下:
          ? CLOSED --> LISTEN --> SYN_RCVD --> ESTABLISHED --> CLOSE_WAIT --> LAST_ACK --> CLOSED
          客戶端的正常狀態(tài)轉(zhuǎn)換過程如下:
          CLOSED --> SYN_SENT --> ESTABLISHED --> FIN_WAIT_1 --> FIN_WAIT_2 --> TIME_WAIT --> CLOSED
          從上面的連接狀態(tài)轉(zhuǎn)換中可以看出,從ESTABLISHED狀態(tài)的轉(zhuǎn)換有兩種,對于客戶端和服務(wù)器端來說,是一樣的,即當(dāng)收到FIN數(shù)據(jù)報之前,主動關(guān)閉,則轉(zhuǎn)換成FIN_WAIT_1;如果因為收到FIN數(shù)據(jù)報,而引起的被動關(guān)閉,則轉(zhuǎn)換成CLOSE_WAIT狀態(tài)。

          posted on 2009-02-09 18:11 ideame 閱讀(2466) 評論(1)  編輯  收藏 所屬分類: Linux

          評論

          # re: TCP連接的過程  回復(fù)  更多評論   

          請問:我的send函數(shù)在默認(rèn)得阻塞模式下工作,每次我要發(fā)送大概4萬多字節(jié)得一個圖片信息,可是每次只發(fā)送不到一萬字節(jié)就發(fā)送失敗,返回-1,錯誤號10054,找了好久也找不到答案,忘高手指點
          2009-08-31 17:05 | kinail
          主站蜘蛛池模板: 灌南县| 宁阳县| 吉木乃县| 赤壁市| 吴江市| 托克逊县| 安塞县| 辽阳市| 湘阴县| 仁寿县| 贵德县| 南皮县| 乌拉特中旗| 岑巩县| 丽江市| 富民县| 礼泉县| 百色市| 阳东县| 金坛市| 元氏县| 师宗县| 两当县| 黄石市| 东海县| 勐海县| 安义县| 马公市| 阳山县| 科尔| 株洲市| 阿勒泰市| 绵阳市| 霍州市| 昌乐县| 肇庆市| 临洮县| 陇西县| 历史| 搜索| 科技|