TCP

傳輸控制協(xié)議 TCP(Transmission Control Protocol)

  • 特點
    是面向連接的铛漓,提供可靠交付愕贡,有流量控制潦嘶,擁塞控制创南,提供全雙工通信伦忠,面向字節(jié)流(把應(yīng)用層傳下來的報文看成字節(jié)流,把字節(jié)流組織成大小不等的數(shù)據(jù)塊)稿辙,每一條 TCP 連接只能是點對點的(一對一)昆码。

  • 首部

    image.png

    選項: 0~40字節(jié)

  • TCP校驗和的實現(xiàn)
    TCP校驗和由發(fā)送端計算,接收端驗證邻储。目的是為了發(fā)現(xiàn)TCP首部和數(shù)據(jù)在發(fā)送端到接收端之間發(fā)生的任何改動未桥。TCP校驗和覆蓋TCP首部和TCP數(shù)據(jù),校驗和是必須的芥备,并要加上12字節(jié)的偽首部(數(shù)據(jù)從IP數(shù)據(jù)報頭獲取冬耿,目的是讓TCP檢查數(shù)據(jù)是否已正確到達目的地)。
    首先萌壳,把偽首部亦镶、TCP報頭日月、TCP數(shù)據(jù)分為16位的字,如果總長度為奇數(shù)個字節(jié)缤骨,則在最后增添一個位都為0的字節(jié)爱咬。把TCP報頭中的校驗和字段置為0
    然后,用反碼相加法累加所有的16位字(進位也要累加)
    最后绊起,對計算結(jié)果取反精拟,作為TCP的校驗和

  • 連接管理
    三次握手和四次揮手的原理

  1. 三次握手建立
    在socket編程中,客戶端執(zhí)行connect()操作即可觸發(fā)三次握手
    image.png
  • 第一步:客戶機的TCP首先向服務(wù)器的 TCP 發(fā)送一個連接請求報文段虱歪。這個特殊的報文段中不含應(yīng)用層數(shù)據(jù)蜂绎,其首部中的 SYN 標志位被置為1.另外,客戶機會隨機選擇一個起始序號 seq=x (連接請求報文不攜帶數(shù)據(jù)笋鄙,但要消耗掉一個序號)师枣。然后客戶端進入 SYN-SENT 狀態(tài),等待服務(wù)器的確認
  • 第二步:服務(wù)器的 TCP 收到連接請求報文后萧落,如同意建立連接践美,就向客戶機發(fā)回確認,并為該 TCP 連接分配 TCP 緩存和變量找岖。在確認報文段中陨倡,SYN 和 ACK 位都被置為 1 ,確認號字段ack的值為 x+1许布,并且服務(wù)器隨機產(chǎn)生起始序號 seq=y (確認報文不攜帶數(shù)據(jù)兴革,但也要消耗掉一個序號)。確認報文段同樣不包含應(yīng)用層數(shù)據(jù)爹脾。
  • 第三步:當客戶機收到確認報文段后帖旨,還要向服務(wù)器給出確認箕昭,并且也要給該連接分配緩存和變量灵妨。這個報文段的 ACK 標志為被置 1,序號字段seq為 x+1落竹,確認號字段 ack=y+1泌霍。該報文段可以攜帶數(shù)據(jù),如果不攜帶數(shù)據(jù)則不消耗序號述召。

為什么 "三次握手" 而不是 "兩次握手" 建立連接:
防止兩次握手情況下已失效的連接請求報文突然又傳送到服務(wù)器而產(chǎn)生錯誤朱转。
三次握手的目的:確認對方的接收與發(fā)送能力是否正常。
考慮客戶A向服務(wù)器B發(fā)出TCP連接請求:
第一個連接請求報文在網(wǎng)絡(luò)的某個結(jié)點長時間滯留积暖,A超時后認為報文丟失藤为,于是再重傳一次連接請求,B收到后建立連接夺刑。
數(shù)據(jù)傳輸完畢后雙方斷開連接缅疟。而此時分别,前一個滯留在網(wǎng)絡(luò)中的連接請求到達服務(wù)器B,而B認為A又發(fā)來連接請求存淫,
此時若使用“三次握手”耘斩,則B向A返回確認報文段,由于是一個失效的請求桅咆,因此A 不予理睬括授,建立連接失敗。
若采用“兩次握手”岩饼,則這種情況下B認為傳輸連接已經(jīng)建立荚虚,并一直等待A傳輸數(shù)據(jù),而A此時并沒有連接請求忌愚,因此不予理睬曲管,這樣就白白浪費B的資源。
半連接: 服務(wù)器第一次收到客戶端的SYN之后硕糊,就會處于SYN_RCVD狀態(tài)院水,此時雙方還沒有完全建立連接,服務(wù)器把此種狀態(tài)下請求連接放在一個隊列中简十,這種隊列稱之為半連接隊列
全連接: 已完成三次握手檬某,建立起連接的就會放在全連接隊列中。如果隊列滿就可能出現(xiàn)丟包現(xiàn)象螟蝙。
三次握手是否可以攜帶數(shù)據(jù): 第一次恢恼、第二次握手不可以攜帶數(shù)據(jù)。因為第一次握手若攜帶數(shù)據(jù)胰默,會讓服務(wù)器更加容易受到SYN攻擊场斑。第三次的話,客戶端已經(jīng)處于ESTABLISHED狀態(tài)牵署,對于客戶端來說漏隐,已經(jīng)建立起連接,并知道服務(wù)器的接收奴迅,發(fā)送能力正常青责,所以能攜帶數(shù)據(jù)。
SYN攻擊:
服務(wù)器的資源分配是在第二次握手時分配取具,客戶端資源是在完成三次握手時分配脖隶。,所以服務(wù)器容易受到SYN洪泛攻擊暇检。SYN攻擊就是Client短時間內(nèi)偽造大量不存在的IP地址产阱,并向Server不斷發(fā)送SYN包,Server則回復(fù)確認包块仆,并等待Client確認构蹬,由于源地址不存在酿矢,因此Server需要不斷重發(fā)直至超時,這些偽造的SYN包將長時間占用未連接隊列怎燥,導(dǎo)致正常的SYN請求因為隊列滿而被丟棄瘫筐,從而引起網(wǎng)絡(luò)擁塞甚至系統(tǒng)癱瘓。SYN攻擊是一種典型的Dos/DDos攻擊铐姚。

解決策略:
SYN cookies技術(shù)當服務(wù)器接受到 SYN 報文段時策肝,不直接為該 TCP 分配資源,而只是打開一個半開的套接字隐绵。接著會使用 SYN 報文段的源 Id之众,目的 Id,端口號以及只有服務(wù)器自己知道的一個秘密函數(shù)生成一個 cookie依许,并把 cookie 作為序列號響應(yīng)給客戶端棺禾。
如果客戶端是正常建立連接,將會返回一個確認字段為 cookie + 1 的報文段峭跳。接下來服務(wù)器會根據(jù)確認報文的源 Id膘婶,目的 Id,端口號以及秘密函數(shù)計算出一個結(jié)果蛀醉,如果結(jié)果的值 + 1 等于確認字段的值悬襟,則證明是剛剛請求連接的客戶端,這時候才為該 TCP 分配資源拯刁,這樣一來就不會為惡意攻擊的 SYN 報文段分配資源空間脊岳,避免了攻擊。
過濾網(wǎng)關(guān)防護
增加最大半連接數(shù)
縮短超時(SYN Timeout)時間

  1. 四次揮手
    在socket編程中垛玻,任何一方執(zhí)行close()操作即可產(chǎn)生揮手操作
    四次揮手釋放TCP連接
  • 第一步:客戶端打算關(guān)閉連接割捅,就向其 TCP 發(fā)送一個連接釋放報文段,并停止再發(fā)送數(shù)據(jù)帚桩,主動關(guān)閉 TCP 連接亿驾,該報文的 FIN 標志位被置為 1,seq=u朗儒,它等于前面已傳送過的數(shù)據(jù)的最夠一個字節(jié)的序號加 1 (FIN 報文段即使不攜帶數(shù)據(jù)颊乘,也要消耗掉一個序號)参淹。TCP 是全雙工的醉锄,即可以想象成是一條 TCP 連接上的兩條數(shù)據(jù)通路。當發(fā)送 FIN 報文時浙值,發(fā)送 FIN 的一端就不能再發(fā)送數(shù)據(jù)恳不,也就是關(guān)閉了其中一條數(shù)據(jù)通路,但對方還可以發(fā)送數(shù)據(jù)
  • 第二步:服務(wù)器收到連接釋放報文段后即發(fā)出確認开呐,確認號是 ack=u+1烟勋,而這個報文段自己的序號是 v规求,等于它前面已傳送過的數(shù)據(jù)的最后一個字節(jié)的序號加 1。此時卵惦,從客戶機到服務(wù)器這個方向的連接就釋放了阻肿,TCP 連接處于半關(guān)閉狀態(tài)。但服務(wù)器若發(fā)送數(shù)據(jù)沮尿,客戶機仍要接收丛塌,即從服務(wù)器到客戶機這個方向的連接并未關(guān)閉
  • 第三步:若服務(wù)器已經(jīng)沒有要向客戶機發(fā)送的數(shù)據(jù),就通知 TCP 釋放連接畜疾,此時其發(fā)出 FIN=1 的連接釋放報文段
  • 第四步:客戶機收到連接釋放報文段后赴邻,必須發(fā)出確認。在確認報文段中啡捶,ACK 字段被置為 1姥敛,確認號 ack=w+1,序號 seq=u+1瞎暑。此時 TCP 連接還沒有釋放掉彤敛,必須等待時間計時器設(shè)置的時間 2MSL 后,A 才進入到連接關(guān)閉狀態(tài)了赌。
    常用的三個狀態(tài)是:ESTABLISHED 表示正在通信臊泌,TIME_WAIT 表示主動關(guān)閉,CLOSE_WAIT 表示被動關(guān)閉揍拆。
    TIME_WAIT 狀態(tài)存在的必要性
  1. 客戶端最后向服務(wù)器發(fā)送的確認 ACK 是有可能丟失的(可靠的關(guān)閉TCP連接渠概。)
    為了保證 客戶端發(fā)送的最后一個確認報文段能夠到達服務(wù)器端。如果 客戶端 不等待 2MSL嫂拴,在此期間若 客戶端返回的最后確認報文段丟失播揪,則 服務(wù)器不能進入正常關(guān)閉狀態(tài),而 客戶端此時已經(jīng)關(guān)閉筒狠,也不可能再重傳猪狈。
  2. 避免新舊連接混雜(.防止上一次連接中的包,迷路后重新出現(xiàn)辩恼,影響新連接(經(jīng)過2MSL雇庙,上一次連接中所有的重復(fù)包都會消失))
    客戶端在發(fā)送完最后一個確認報文段后,再經(jīng)過 2MSL 可保證本連接持續(xù)的時間內(nèi)所產(chǎn)生的所有報文段從網(wǎng)絡(luò)中消失灶伊。
    假設(shè)沒有time-wait 限制疆前,因某些原因我們先關(guān)閉這條TCP連接,然后很快又以相同的<源ip,源port,目的ip,目的port> 建立一個新的TCP連接聘萨,然后發(fā)送數(shù)據(jù)竹椒,設(shè)想此時前一個連接在網(wǎng)絡(luò)中滯留的數(shù)據(jù)報現(xiàn)在到達接收方,會被當做正常數(shù)據(jù)接收并上傳到應(yīng)用層米辐,而這些舊數(shù)據(jù)不應(yīng)該被接收胸完。從而引起數(shù)據(jù)錯亂而導(dǎo)致各種無法預(yù)知詭異錯誤
    服務(wù)器保持大量的time-wait 狀態(tài)如何避免
  3. 讓服務(wù)器能夠快速回收和重用那些TIME_WAIT的資源书释。
#表示開啟重用。允許將TIME-WAIT sockets重新用于新的TCP連接赊窥,默認為0爆惧,表示關(guān)閉  
net.ipv4.tcp_tw_reuse = 1  
#表示開啟TCP連接中TIME-WAIT sockets的快速回收,默認為0锨能,表示關(guān)閉  
net.ipv4.tcp_tw_recycle = 1  

這篇文章講得不錯

  1. SO_REUSEADDR 套接字(so_resueaddr)
    首先服務(wù)器可以設(shè)置 SO_REUSEADDR 套接字選項來通知內(nèi)核检激,如果端口忙,但TCP連接位于TIME_WAIT狀態(tài)時可以重用端口腹侣。在一個非常有用的場景就是叔收,如果你的服務(wù)器程序停止后想立即重啟,而新的套接字依舊希望使用同一端口傲隶,此時SO_REUSEADDR選項就可以避免TIME_WAIT狀態(tài)饺律。
    服務(wù)器出現(xiàn)了大量 CLOSE_WAIT 狀態(tài)如何解決
    說明在對方關(guān)閉連接之后服務(wù)器程序自己沒有進一步發(fā)出ack信號。換句話說跺株,就是在對方連接關(guān)閉之后复濒,程序里沒有檢測到,或者程序壓根就忘記了這個時候需要關(guān)閉連接乒省,于是這個資源就一直被程序占著巧颈。
    解決方法:檢查代碼,特別是釋放資源的代碼袖扛,或者是處理請求的線程配置砸泛。
    流量控制和擁塞控制
    流量控制和擁塞控制2

TCP擁塞控制

發(fā)送方根據(jù)自己的網(wǎng)絡(luò)擁塞程度設(shè)置cwnd(擁塞窗口)的值來限制發(fā)送速率

  • 方法
    ssthtresh是慢開始門限值
  1. 慢開始算法
    cwnd<ssthresh,每收到一個對新報文段的確認后蛆封,將cwnd加1
  • 擁塞避免算法
    cwnd>ssthresh時唇礁,每經(jīng)過一個往返時延RTT,cwnd就增加一個
  • 快重傳
    當收到連續(xù)的三個重復(fù)ACK惨篱,直接重傳對方期待的報文
  • 快恢復(fù)
    當收到三個連續(xù)的冗余ACK(即重復(fù)確認)盏筐,執(zhí)行“乘法減少”算法,令ssthresh=cwnd=cwnd/2


    image.png

TCP流量控制

TCP提供一種基于滑動窗口協(xié)議的流量控制機制砸讳,接收方根據(jù)自己接收緩存的大小琢融,動態(tài)調(diào)整發(fā)送方的發(fā)送窗口大小。
滑動窗口的基本原理:
由接收方控制發(fā)送方發(fā)送數(shù)據(jù)的速率簿寂。
停止-等待協(xié)議: 發(fā)送窗口大小 =1 漾抬,接收窗口大小 = 1.保證有序接收
后退N幀協(xié)議: 發(fā)送窗口大小>1,接收窗口大小 =1.保證有序接收
選擇重傳協(xié)議: 發(fā)送窗口大小>1陶耍,接收窗口大小>1.
#######滑動窗口奋蔚、窗口她混、擁塞窗口的區(qū)分烈钞?
滑動窗口:批量發(fā)送報文的大小泊碑,提高發(fā)送報文的效率
擁塞窗口:當前網(wǎng)絡(luò)可能造成擁堵的一個上限值/閾值
窗口:對象能接受的當前的最大的報文值
滑動窗口 = min[窗口,擁塞窗口]

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末毯欣,一起剝皮案震驚了整個濱河市馒过,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌酗钞,老刑警劉巖腹忽,帶你破解...
    沈念sama閱讀 216,919評論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異砚作,居然都是意外死亡窘奏,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,567評論 3 392
  • 文/潘曉璐 我一進店門葫录,熙熙樓的掌柜王于貴愁眉苦臉地迎上來着裹,“玉大人,你說我怎么就攤上這事米同『龋” “怎么了?”我有些...
    開封第一講書人閱讀 163,316評論 0 353
  • 文/不壞的土叔 我叫張陵面粮,是天一觀的道長少孝。 經(jīng)常有香客問我,道長熬苍,這世上最難降的妖魔是什么稍走? 我笑而不...
    開封第一講書人閱讀 58,294評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮柴底,結(jié)果婚禮上钱磅,老公的妹妹穿的比我還像新娘。我一直安慰自己似枕,他們只是感情好盖淡,可當我...
    茶點故事閱讀 67,318評論 6 390
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著凿歼,像睡著了一般褪迟。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上答憔,一...
    開封第一講書人閱讀 51,245評論 1 299
  • 那天味赃,我揣著相機與錄音,去河邊找鬼虐拓。 笑死心俗,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播城榛,決...
    沈念sama閱讀 40,120評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼揪利,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了狠持?” 一聲冷哼從身側(cè)響起疟位,我...
    開封第一講書人閱讀 38,964評論 0 275
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎喘垂,沒想到半個月后甜刻,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,376評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡正勒,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,592評論 2 333
  • 正文 我和宋清朗相戀三年得院,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片章贞。...
    茶點故事閱讀 39,764評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡尿招,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出阱驾,到底是詐尸還是另有隱情就谜,我是刑警寧澤,帶...
    沈念sama閱讀 35,460評論 5 344
  • 正文 年R本政府宣布里覆,位于F島的核電站丧荐,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏喧枷。R本人自食惡果不足惜虹统,卻給世界環(huán)境...
    茶點故事閱讀 41,070評論 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望隧甚。 院中可真熱鬧车荔,春花似錦、人聲如沸戚扳。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,697評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽帽借。三九已至珠增,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間砍艾,已是汗流浹背蒂教。 一陣腳步聲響...
    開封第一講書人閱讀 32,846評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留脆荷,地道東北人凝垛。 一個月前我還...
    沈念sama閱讀 47,819評論 2 370
  • 正文 我出身青樓懊悯,卻偏偏與公主長得像,于是被迫代替她去往敵國和親梦皮。 傳聞我的和親對象是個殘疾皇子炭分,可洞房花燭夜當晚...
    茶點故事閱讀 44,665評論 2 354