• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            兔子的技術(shù)博客

            兔子

               :: 首頁 :: 聯(lián)系 :: 聚合  :: 管理
              202 Posts :: 0 Stories :: 43 Comments :: 0 Trackbacks

            留言簿(10)

            最新評論

            閱讀排行榜

            評論排行榜

            建立一個 TCP 連接TCP 是一個面向連接的協(xié)議,無論哪一方向另一方發(fā)送數(shù)據(jù)之前,都必須先在雙方之間建立一條連接。本節(jié)將詳細討論一個TCP 連接是如何建立的以及通信結(jié)束后是如何終止的。

            TCP使用三次握手 ( three-way handshake ) 協(xié)議來建立連接,圖 3-10 描述了三次握手的報文序列。這三次握手為:

                   請求端(通常稱為客戶)發(fā)送一個 SYN 報文段( SYN 為 1 )指明客戶打算連接的服務(wù)器的端口,以及初始順序號( ISN )。

                   服務(wù)器發(fā)回包含服務(wù)器的初始順序號的 SYN 報文段( SYN 為 1 )作為應(yīng)答。同時,將確認號設(shè)置為客戶的 ISN 加 1 以對客戶的 SYN 報文段進行確認( ACK 也為 1 )。

                   客戶必須將確認號設(shè)置為服務(wù)器的 ISN 加 1 以對服務(wù)器的 SYN 報文段進行確認( ACK 為 1 ),該報文通知目的主機雙方已完成連接建立。


                   三次握手協(xié)議是連接兩端正確同步的充要條件。因為 TCP 建立在不可靠的分組傳輸服務(wù)之上,報文可能丟失、延遲、重復(fù)和亂序,因此協(xié)議必須使用超時和重傳機制。如果重傳的連接請求和原先的連接請求在連接正在建立時到達,或者當(dāng)一個連接已經(jīng)建立、使用和結(jié)束之后,某個延遲的連接請求才到達,就會出現(xiàn)問題。采用三次握手協(xié)議(加上這樣的規(guī)則:在連接建立之后 TCP 就不再理睬又一次的連接請求)就可以解決這些問題。

              三次握手協(xié)議可以完成兩個重要功能:它確保連接雙方做好傳輸準備,并使雙方統(tǒng)一了初始順序號。初始順序號是在握手期間傳輸順序號并獲得確認:當(dāng)一端為建立連接而發(fā)送它的 SYN 時,它為連接選擇一個初始順序號;每個報文段都包括了順序號字段和確認號字段,這使得兩臺機器僅僅使用三個握手報文就能協(xié)商好各自的數(shù)據(jù)流的順序號。一般來說, ISN 隨時間而變化,因此每個連接都將具有不同的ISN 。

            關(guān)閉一個 TCP 連接

                   TCP 連接建立起來后,就可以在兩個方向傳送數(shù)據(jù)流。當(dāng) TCP 的應(yīng)用進程再沒有數(shù)據(jù)需要發(fā)送時,就發(fā)關(guān)閉命令。 TCP 通過發(fā)送控制位 FIN=1 的數(shù)據(jù)片來關(guān)閉本方數(shù)據(jù)流,但還可以繼續(xù)接收數(shù)據(jù),直到對方關(guān)閉那個方向的數(shù)據(jù)流,連接就關(guān)閉。

                    TCP 協(xié)議使用修改的三次握手協(xié)議來關(guān)閉連接, 如圖 3-11 所示,即終止一個連接要經(jīng)過 4 次握手。這是因為 TCP 的半關(guān)閉( half-close )造成的。由于一個 TCP 連接是全雙工(即數(shù)據(jù)在兩個方向上能同時傳遞),因此每個方向必須單獨地進行關(guān)閉。關(guān)閉的原則就是當(dāng)一方完成它的數(shù)據(jù)發(fā)送任務(wù)后就能發(fā)送一個 FIN 來終止這個方向連接。當(dāng)一端收到一個 FIN ,它必須通知應(yīng)用層另一端已經(jīng)終止了那個方向的數(shù)據(jù)傳送。發(fā)送 FIN 通常是應(yīng)用層進行關(guān)閉的結(jié)果。


              從一方的 TCP 來說,連接的關(guān)閉有三種情況:

              本方啟動關(guān)閉

              收到本方應(yīng)用進程的關(guān)閉命令后, TCP 在發(fā)送完尚未處理的報文段后,發(fā) FIN = 1 的報文段給對方,且 TCP 不再受理本方應(yīng)用進程的數(shù)據(jù)發(fā)送。在 FIN 以前發(fā)送的數(shù)據(jù)字節(jié),包括 FIN ,都需要對方確認,否則要重傳。注意 FIN 也占一個順序號。一旦收到對方對 FIN 的確認以及對方的 FIN 報文段,本方 TCP 就對該 FIN 進行確認,在等待一段時間,然后關(guān)閉連接。等待是為了防止本方的確認報文丟失,避免對方的重傳報文干擾新的連接。

               對方啟動關(guān)閉

                    TCP 收到對方發(fā)來的 FIN 報文時,發(fā) ACK 確認此 FIN 報文,并通知應(yīng)用進程連接正在關(guān)閉。應(yīng)用進程將以關(guān)閉命令響 應(yīng)。 TCP 在發(fā)送完尚未處理的報文段后,發(fā)一個 FIN 報文給對方 TCP ,然后等待對方對 FIN 的確認,收到確認后關(guān)閉連接。若對方的確認未及時到達,在等待一段時間后也關(guān)閉連接。

              雙方同時啟動關(guān)閉

                   連接雙方的應(yīng)用進程同時發(fā)關(guān)閉命令,則雙方 TCP 在發(fā)送完尚未處理的報文段后,發(fā)送 FIN 報文。各方 TCP 在 FIN 前所發(fā)報文都得到確認后,發(fā) ACK 確認它收到的 FIN 。各方在收到對方對 FIN 的確認后,同樣等待一段時間再關(guān)閉連接。這稱之為同時關(guān)閉( simultaneous close )。

            TCP 狀態(tài)機

              TCP 協(xié)議的操作可以使用一個具有 11 種狀態(tài)的有限狀態(tài)機( Finite State Machine )來表示,圖 3-12 描述了 TCP 的有限狀態(tài)機,圖中的圓角矩形表示狀態(tài),箭頭表示狀態(tài)之間的轉(zhuǎn)換,各狀態(tài)的描述如表 3-2 所示。圖中用粗線表示客戶端主動和被動的服務(wù)器端建立連接的正常過程:客戶端的狀態(tài)變遷用粗實線,服務(wù)器端的狀態(tài)變遷用粗虛線。細線用于不常見的序列,如復(fù)位、同時打開、同時關(guān)閉等。圖中的每條狀態(tài)變換線上均標有“事件/動作”:事件是指用戶執(zhí)行了系統(tǒng)調(diào)用( CONNECT 、 LISTEN 、 SEND 或 CLOSE )、收到一個報文段( SYN 、 FIN 、 ACK 或 RST )、或者是出現(xiàn)了超過兩倍最大的分組生命期的情況;動作是指發(fā)送一個報文段( SYN 、 FIN 或 ACK )或什么也沒有(用“-”表示)。


            圖 3-12 TCP 有限狀態(tài)機。粗實線表示客戶的正常路徑;
            粗虛線表示服務(wù)器的正常路徑;細線表示不常見的事件。

              每個連接均開始于CLOSED 狀態(tài)。當(dāng)一方執(zhí)行了被動的連接原語LISTEN或主動的連接原語CONNECT時,它便會脫離CLOSED狀態(tài)。如果此時另一方執(zhí)行了相對應(yīng)的連接原語,連接便建立了,并且狀態(tài)變?yōu)镋STABLISHED 。任何一方均可以首先請求釋放連接,當(dāng)連接被釋放后,狀態(tài)又回到了CLOSED 。

            表 3-2 TCP 狀態(tài)表

            狀 態(tài)

            描 述

            CLOSED

            關(guān)閉狀態(tài),沒有連接活動或正在進行

            LISTEN

            監(jiān)聽狀態(tài),服務(wù)器正在等待連接進入

            SYN RCVD

            收到一個連接請求,尚未確認

            SYN SENT

            已經(jīng)發(fā)出連接請求,等待確認

            ESTABLISHED

            連接建立,正常數(shù)據(jù)傳輸狀態(tài)

            FIN WAIT 1

            (主動關(guān)閉)已經(jīng)發(fā)送關(guān)閉請求,等待確認

            FIN WAIT 2

            (主動關(guān)閉)收到對方關(guān)閉確認,等待對方關(guān)閉請求

            TIMED WAIT

            完成雙向關(guān)閉,等待所有分組死掉

            CLOSING

            雙方同時嘗試關(guān)閉,等待對方確認

            CLOSE WAIT

            (被動關(guān)閉)收到對方關(guān)閉請求,已經(jīng)確認

            LAST ACK

            (被動關(guān)閉)等待最后一個關(guān)閉確認,并等待所有分組死掉

            1. 正常狀態(tài)轉(zhuǎn)換

            我們用圖3-13 來顯示在正常的TCP 連接的建立與終止過程中,客戶與服務(wù)器所經(jīng)歷的不同狀態(tài)。讀者可以對照圖 3-12 來閱讀,使用圖3-12 的狀態(tài)圖來跟蹤圖3-13 的狀態(tài)變化過程,以便明白每個狀態(tài)的變化:

            • 服務(wù)器端首先執(zhí)行LISTEN 原語進入被動打開狀態(tài)(LISTEN),等待客戶端連接;

            • 當(dāng)客戶端的一個應(yīng)用程序發(fā)出CONNECT命令后,本地的TCP 實體為其創(chuàng)建一個連接記錄并標記為SYN SENT 狀態(tài),然后給服務(wù)器發(fā)送一個SYN 報文段;

            • 服務(wù)器收到一個 SYN 報文段,其TCP 實體給客戶端發(fā)送確認 ACK 報文段同時發(fā)送一個 SYN 信號,進入 SYN RCVD 狀態(tài);

            • 客戶端收到SYN + ACK 報文段,其TCP 實體給服務(wù)器端發(fā)送出三次握手的最后一個 ACK 報文段,并轉(zhuǎn)換為ESTABLISHED狀態(tài);

            • 服務(wù)器端收到確認的ACK報文段,完成了三次握手,于是也進入ESTABLISHED 狀態(tài)。

               在此狀態(tài)下,雙方可以自由傳輸數(shù)據(jù)。當(dāng)一個應(yīng)用程序完成數(shù)據(jù)傳輸任務(wù)后,它需要關(guān)閉TCP連接。假設(shè)仍由客戶端發(fā)起主動關(guān)閉連接。

            • 客戶端執(zhí)行CLOSE原語,本地的TCP 實體發(fā)送一個FIN 報文段并等待響應(yīng)的確認進入狀態(tài)FIN WAIT 1 ;

            • 服務(wù)器收到一個 FIN 報文段,它確認客戶端的請求發(fā)回一個 ACK 報文段,進入CLOSE WAIT狀態(tài);

            • 客戶端收到確認ACK報文段,就轉(zhuǎn)移到FIN WAIT 2狀態(tài),此時連接在一個方向上就斷開了;

            • 服務(wù)器端應(yīng)用得到通告后,也執(zhí)行CLOSE原語關(guān)閉另一個方向的連接,其本地TCP 實體向客戶端發(fā)送一個 FIN 報文段,并進入LAST ACK 狀態(tài),等待最后一個 ACK 確認報文段;

            • 客戶端收到FIN報文段并確認,進入TIMED WAIT 狀態(tài),此時雙方連接均已經(jīng)斷開,但TCP 要等待一個2倍報文段最大生存時間MSL( Maximum Segment Lifetime ),確保該連接的所有分組全部消失,以防止出現(xiàn)確認丟失的情況。當(dāng)定時器超時后,TCP 刪除該連接記錄,返回到初始狀態(tài)(CLOSED)。

            • 服務(wù)器收到最后一個確認 ACK 報文段,其TCP 實體便釋放該連接,并刪除連接記錄,返回到初始狀態(tài)( CLOSED )。


            2. 同時打開:

            盡管發(fā)生的可能性極小,兩個應(yīng)用程序同時彼此執(zhí)行主動打開的情況還是可能的。每一方必須發(fā)送一個 SYN ,且這些 SYN 必須傳遞給對方。這需要每一方使用一個對方周知的端口作為本地端口。例如,主機 A 中的一個應(yīng)用程序使用本地端口 7777 ,并與主機 B 的端口 8888 執(zhí)行主動打開。主機 B 中的應(yīng)用程序則使用本地端口 8888 ,并與主機 A 的端口 7777 執(zhí)行主動打開。 TCP 是特意設(shè)計為了可以處理同時打開,對于同時打開它僅建立一條連接而不是兩條連接(其他的協(xié)議族,最突出的是 OSI 傳輸層,在這種情況下將建立兩條連接而不是一條連接)。

              當(dāng)出現(xiàn)同時打開的情況時,狀態(tài)變遷與圖 3-13 所示的不同。兩端幾乎在同時發(fā)送 SYN ,并進入 SYN_SENT 狀態(tài)。當(dāng)每一端收到 SYN 時,狀態(tài)變?yōu)?SYN_RCVD ,同時它們都再發(fā) SYN 并對收到的 SYN 進行確認。當(dāng)雙方都收到 SYN 及相應(yīng)的 ACK 時,狀態(tài)都變遷為 ESTABLISHED 。圖 3-14 顯示了這些狀態(tài)變遷過程。


            圖 3-14 同時打開期間報文段的交換

             

              一個同時打開的連接需要交換 4 個報文段,比正常的三次握手多一個。此外,要注意的是我們沒有將任何一端稱為客戶或服務(wù)器,因為每一端既是客戶又是服務(wù)器。

            3. 同時關(guān)閉:

                   正常情況下都是由一方(通常但不總是客戶方)發(fā)送第一個 FIN 執(zhí)行主動關(guān)閉,但雙方都執(zhí)行主動關(guān)閉也是可能的, TCP 協(xié)議也允許這樣的同時關(guān)閉。

                   在圖3-12 中,當(dāng)兩端應(yīng)用層同時發(fā)出關(guān)閉命令時,兩端均從ESTABLISHED 變?yōu)镕IN_WAIT_1 。這將導(dǎo)致雙方各發(fā)送一個FIN ,兩個FIN 經(jīng)過網(wǎng)絡(luò)傳送后分別到達另一端。收到FIN 后,狀態(tài)由FIN_WAIT_1變遷到 CLOSING ,并發(fā)送最后的ACK 。當(dāng)收到最后的ACK 時,狀態(tài)變化為TIME_WAIT 。圖3-15 總結(jié)了這些狀態(tài)的變化,從圖中可以看出同時關(guān)閉與正常關(guān)閉使用的報文段交換數(shù)目相同。


            圖 3-15 同時關(guān)閉期間的報文段交換

            4. 其它情況:

            服務(wù)方打開:從LISTEN到SYN_SENT的變遷是正確的,它由服務(wù)器端主動發(fā)出 SYN 報文段,但 Berkeley 版的 TCP 軟件并不支持它。

            重置連接(復(fù)位):只有當(dāng) SYN_RCVD 狀態(tài)是從LISTEN 狀態(tài)(正常情況)進入,而不是從SYN_SENT狀態(tài)(同時打開)進入時,從SYN_RCVD 回到LISTEN 的狀態(tài)變遷才是有效的。這意味著如果我們執(zhí)行被動打開(進入 LISTEN ),收到一個 SYN ,發(fā)送一個帶ACK 的SYN(進入 SYN_RCVD ),然后收到一個 RST ,而不是一個 ACK ,便又回到 LISTEN 狀態(tài)并等待另一個連接請求的到來。

            快速關(guān)閉:在主動關(guān)閉后的FIN_WAIT_1狀態(tài),如果收到的報文段不僅是ACK ,而且還包括對方的 FIN 信號,則直接進入 TIME_WAIT 狀態(tài),給對方發(fā)送 ACK 報文段,然后等待超時。

              另外, TIME_WAIT 狀態(tài)的等待超時需要再詳細解釋一下,因為它直接影響到網(wǎng)絡(luò)應(yīng)用程序的表現(xiàn)。

            每個具體 TCP 實現(xiàn)必須選擇一個報文段最大生存時間 MSL ( Maximum Segment Lifetime ),它是任何報文段被丟棄前在網(wǎng)絡(luò)內(nèi)的最長時間。我們知道這個時間是有限的,因為 TCP 報文段以 IP 數(shù)據(jù)報在網(wǎng)絡(luò)內(nèi)傳輸,而 IP 數(shù)據(jù)報有限制其生存時間的 TTL 字段。 RFC 793 [Postel 1981c ] 指出 MSL 為 2 分鐘。然而,實現(xiàn)中的常用值是 30 秒、 1 分鐘、或 2 分鐘。

              對一個具體實現(xiàn)所給定的 MSL 值,處理的原則是:當(dāng) TCP 執(zhí)行一個主動關(guān)閉,并發(fā)回最后一個 ACK ,該連接必須在 TIME_WAIT 狀態(tài)停留的時間為 2 倍的 MSL ,因此 TIME_WAIT 狀態(tài)也稱為 2MSL 等待狀態(tài)。在這段時間內(nèi),如果最后的 ACK 丟失,對方會超時并重發(fā)最后的 FIN ,這樣本地 TCP 可以再次發(fā)送 ACK 報文段(這也是它唯一可以發(fā)送的報文,并重置 2MSL 定時器)。

              這種 2MSL 等待的另一個結(jié)果是這個 TCP 連接在 2MSL 等待期間,定義這個連接的套接字( socket ,客戶的 IP 地址和端口號,服務(wù)器的 IP 地址和端口號)不能再被使用。這個連接只能在 2MSL 結(jié)束后才能再被使用。在連接處于 2MSL 等待時,任何遲到的報文段將被丟棄。

              我們假設(shè)圖 3-12 中是客戶執(zhí)行主動關(guān)閉并進入 TIME_WAIT ,這是正常的情況,因為服務(wù)器通常執(zhí)行被動關(guān)閉,不會進入 TIME_WAIT 狀態(tài)。這暗示如果我們終止一個客戶程序,并立即重新啟動這個客戶程序,則這個新客戶程序?qū)⒉荒苤赜孟嗤谋镜囟丝凇_@不會帶來什么問題,因為客戶使用本地端口,而并不關(guān)心這個端口號是什么。然而,對于服務(wù)器,情況就有所不同,因為服務(wù)器使用周知端口。如果我們終止一個已經(jīng)建立連接的服務(wù)器程序,并試圖立即重新啟動這個服務(wù)器程序,服務(wù)器程序?qū)⒉荒馨阉倪@個周知端口賦值給它的端點,因為那個端口是處于 2MSL 連接的一部分。在重新啟動服務(wù)器程序前,它需要在 1~4 分鐘。這就是很多網(wǎng)絡(luò)服務(wù)器程序被殺死后不能夠馬上重新啟動的原因(錯誤提示為“ Address already in use ”)。


            轉(zhuǎn)自:http://blog.163.com/tyw_andy/blog/static/1167902120099293916894/
            posted on 2013-06-08 18:09 會飛的兔子 閱讀(591) 評論(0)  編輯 收藏 引用 所屬分類: 系統(tǒng)API,底層技術(shù)
            久久精品国产99久久无毒不卡 | 国产精品伦理久久久久久| 色播久久人人爽人人爽人人片AV| 91精品国产高清久久久久久国产嫩草| 99国内精品久久久久久久 | 蜜臀久久99精品久久久久久小说| 亚洲国产综合久久天堂 | 国产一区二区精品久久| 狠狠色噜噜狠狠狠狠狠色综合久久 | 一本色综合久久| 国产2021久久精品| 一本久久知道综合久久| 久久99国产精品尤物| 国产精品热久久毛片| 久久精品国产欧美日韩99热| 日韩久久久久中文字幕人妻| 合区精品久久久中文字幕一区| 婷婷久久综合九色综合绿巨人 | 久久久久人妻一区二区三区vr| 99精品久久精品| 久久综合九色综合网站| 久久精品天天中文字幕人妻| 久久ZYZ资源站无码中文动漫| 精品水蜜桃久久久久久久| 日韩人妻无码一区二区三区久久99| 国内精品久久久久久久久电影网 | 天天久久狠狠色综合| 中文字幕久久亚洲一区| aaa级精品久久久国产片| 亚洲午夜福利精品久久| 亚洲精品美女久久777777| 国内精品久久久久久久亚洲| 久久久久久久国产免费看| 久久亚洲精品成人AV| 亚洲人成无码久久电影网站| 伊人久久大香线蕉av不卡| 久久婷婷人人澡人人| 国产精品久久久久aaaa| 亚洲国产精品无码久久久秋霞2| 久久精品国产99久久久香蕉| 亚洲精品乱码久久久久久按摩|