天天日夜夜添_精品国产99久久久久久人裸体 _成人app在线观看_日韩色网站

新聞資訊

    TCP 的特點?怎么理解全雙工?

    全雙工是通訊上的術語,一般在軟件開發領域提到的并不多。

    這是指數據同時在兩個方向上傳輸,TCP 是基于全雙工的可信傳輸協議。

    當然 UDP 也可以實現全雙工的傳輸,但 TCP 只能實現點對點的傳輸,無法支持廣播或者多播(分組)。

    黑板:半雙工的區別在于,同一時間只能有一個方向的傳輸TCP 的數據包如何組織?

    透視一個協議的最原始的方法就是看它的數據包,一個TCP 的報文格式如下:

    這里面的字段就包括了:

    源端口

    表明發送端所使用的端口號,用于目標主機回應。

    目的端口

    表明要連接的目標主機的端口號。

    序號

    表明發送的數據包的順序,一般為上次發送包中的順序號+1。

    若該數據包是整個TCP連接中的第一個包(SYN包),則該值是隨機生成的。

    確認號

    表明本端TCP已經接收到的數據,其值表示期待對端發送的下一個字節的序號。

    實際上告訴對方,在這個序號減1以前的字節已正確接收。

    若該數據包是整個TCP連接中的第一個包(SYN包),則確認號一般為0。

    數據偏移

    表示以32位(4字節)為單位的TCP分組頭的總長度(首部長度),用于確定用戶數據區的起始位置。

    tcp數據包結構_tcp ip協議結構_tcp協議數據包結構

    在沒有可變內容的情況下,TCP頭部的大小為20字節,對應該值為5。

    標志位

    緊急標志位(URG):開啟時表明此數據包處于緊急狀態應該優先處理

    確認標志位(ACK):開啟時表明確認號有效,否則忽略確認號

    推送標志位(PSH):開啟時表明應該盡快交付給應用進程,而不必等到緩存區填滿才推送,比如 的場景

    復位標志位(RST):開啟時表明TCP連接出現連接出現錯誤,數據包非法拒絕連接

    同步標志位(SYN):開啟時表明連接建立的標志

    終止標志位(FIN):開啟時表明釋放一個連接

    窗口大小

    表明期望接受到的數據包字節數,用于擁塞控制。

    校驗和

    實現對TCP報文頭以及數據區進行校驗。

    緊急指針

    在緊急狀態下(URG打開),指出窗口中緊急數據的位置(末端)。

    選項(可變)

    用于支持一些特殊的變量,比如最大分組長度(MSS)。

    填充

    用于保證可變選項為32 bit的整數倍。

    黑板:一般情況下TCP 頭部為20字節,加上20字節的 IP頭部,一個數據包至少包含40字節的頭部三、TCP 工作流程

    鏈是指鏈路,這個是物理層的概念,比如光纜光纖,或是無線的電磁波。

    但這里所說的鏈路其實是網絡連接的意思,即IP 上層的概念。

    tcp數據包結構_tcp協議數據包結構_tcp ip協議結構

    那么,一個TCP 正常的通訊流程,會包含建鏈(建立連接)、傳輸數據、拆鏈(關閉連接),如下圖所示:

    (圖來自網絡)

    據上圖所示,在進行 TCP 進行數據傳輸時,都不可避免的會經過這兩個階段:

    下面,重點說明下建鏈與拆鏈的過程

    四、 三次握手

    在建立TCP連接時,需要經過三次交互,也成為三次握手()。

    1、客戶端發起連接請求,發送 SYN包(SYN=i)到服務器,并進入到SYN-SEND狀態,等待服務器確認

    2、服務器收到SYN包后,必須確認客戶的 SYN(ack=i+1),同時自己也發送一個SYN包(SYN=k),即SYN+ACK包,此時服務器進入SYN-RECV狀態

    3、客戶端收到服務器的SYN+ACK包,向服務器發送確認報ACK(ack=k+1),此后客戶端和服務器進入狀態,雙方可以開始傳送數據。

    在談論三次握手的時候,有幾個問題是需要關注的:

    問題1. 為什么是三次握手

    這個問題在技術面試時屢試不爽,原話是能不能兩次,或者是四次握手呢?

    答案就是,TCP 是可靠的傳輸,在建立連接時就應該經過兩端的確認過程,如上面的流程,

    只有在三次握手的情況下,客戶端和服務端都經過了一次真正(SYN+ACK)的確認過程。這樣的連接便認為是可信的。

    此外,如果僅僅只是兩次握手,一旦網絡不穩定造成 SYN 包重傳則會直接導致重復建立連接,浪費資源。

    問題2. 什么是syn flood攻擊

    syn flood 是一種經典的 ddos攻擊手段,這里面用到了TCP 三次握手存在的漏洞。

    在上面的圖中,可以看到當服務端接收到 SYN 后進入 SYN-RECV 狀態,此時的連接稱為半連接,同時會被服務端寫入一個 半連接隊列。

    想象一下,如果攻擊者在短時間內不斷的向服務端發送大量的 SYN 包而不響應,那么服務器的 半連接隊列很快會被寫滿,從而導致無法工作。

    tcp數據包結構_tcp ip協議結構_tcp協議數據包結構

    實現 syn flood 的手段,可以通過偽造源 IP 的方式,這樣服務器的響應就永遠到達不了客戶端(握手無法完成);

    當然,通過設定客戶端防火墻規則也可以達到同樣的目的。

    對 syn flood 實現攔截是比較困難的,可以通過啟用 的方式實現緩解,但這通常不是最佳方案。

    最好的辦法是通過專業的防火墻來解決,基本上所有的云計算大T 都具備這個能力。

    關于 syn flood 可以看看這篇文章

    問題3. 半連接隊列和全連接隊列如何調優

    這里提到了一個"半連接隊列"(syns queue),與其對應的還有一個 "全連接隊列"( queue)

    前者用于暫存未建立完全的連接,后者是連接在成功建立后進入的一個隊列。

    半連接隊列默認大小可以通過內核參數調整:

    echo 4096 > /proc/sys/net/ipv4/tcp_max_syn_backlog

    黑板: 在 開啟時是無效的,這兩個選項存在沖突

    對于全連接隊列,如果服務器未能及時通過 調用將其中的連接取走,會導致隊列溢出(連接失效)

    全連接隊列的大小的內核調優方式:

    echo 4096 > /proc/sys/net/core/somaxconn

    那么,是不是只有內核調優這種方法能影響這兩個參數呢?答案是否定的。

    實際上,在應用層調用 時也支持設置一個 參數,這幾個之間的關系如下:

    半連接隊列長度 = min(backlog,內核 net.core.somaxconn,內核 tcp_max_syn_backlog)
    全連接隊列長度 = min(backlog,內核 net.core.somaxconn)

    黑板:一般的應用服務器如 netty、 都支持設置 參數,但是在真正進行調優時還需要配合考慮內核參數的配置。五、 四次揮手

    在釋放連接時,由于TCP是全雙工的,因此最后要由兩端分別進行關閉,這個流程如下:

    tcp協議數據包結構_tcp數據包結構_tcp ip協議結構

    1、客戶端發送一個FIN,用來關閉客戶端到服務器的數據傳送,客戶端進入狀態。

    2、服務器收到FIN后,發送一個ACK給客戶端,確認序號為收到序號+1(與SYN相同,一個FIN占用一個序號),服務器進入狀態,而客戶端進入狀態。

    3、服務器發送一個FIN,用來關閉服務器到客戶端的數據傳送,服務器進入狀態。

    4、客戶端收到FIN后,客戶端進入狀態tcp數據包結構,接著發送一個ACK給服務器,確認序號為收到序號+1,服務器進入狀態,完成釋放。

    關閉連接有主動關閉和被動關閉一說,這里為了簡化理解,我們以客戶端作為主動關閉方,服務器為被動關閉方。

    四次揮手需要關注的問題:

    問題1. 為什么是四次揮手

    發送FIN的一方就是主動關閉(客戶端),而另一方則為被動關閉(服務器)。

    當一方發送了FIN,則表示在這一方不再會有數據的發送。

    其中當被動關閉方受到對方的FIN時,此時往往可能還有數據需要發送過去,因此無法立即發送FIN(也就是無法將FIN與ACK合并發送),

    而是在等待自己的數據發送完畢后再單獨發送FIN,因此整個過程需要四次交互。

    問題2. 什么是半關閉

    客戶端在收到第一個FIN的ACK響應后,會進入 狀態時,此時服務器處于 狀態,這種狀態就稱之為半關閉。

    從半關閉到全關閉,需要等待第二次FIN的確認才算結束。此時,客戶端要等到服務器的FIN才能進入,

    如果對方遲遲不發送FIN呢,則會等待一段時間后超時,這個可以通過內核參數控制tcp數據包結構,默認是60s。

    問題3. 為什么服務器會有大量

    半關閉的狀態下的服務器連接會處于 狀態,直到服務器發送了FIN。

    那么在應用層則是調用.close()會執行FIN的發送,如果服務器出現大量狀態的連接,那么有可能的原因:

    問題4. 會帶來什么問題

    當客戶端收到了對方的FIN時,會進入狀態,此時會保持一段時間再進入CLOSE狀態。

    這么做的原因主要還是為了可靠的關閉連接。在將TCP 進行可靠性設計之時就考慮了許多網絡的不穩定性的因素,比如:

    tcp協議數據包結構_tcp ip協議結構_tcp數據包結構

    發送給對方的ACK 可能會無法及時收到,此時對方可能重傳FIN過來,如果提前進入CLOSE則會返回RST而不是ACK,就會影響關閉流程。

    因此 狀態默認會持續一段時間,直到確認不會再有重傳的數據包之后再安全的關閉。

    黑板:這里的持續時間默認是 2*MSL(總共1分鐘),這個MSL叫Max ,也就是關于一個數據包在網絡中傳輸的最大生命周期的預設。

    MSL默認是30s,當然這個值在現在已經可以大幅度縮減。可見在當時在設計之初,網絡狀況有多么的糟糕。

    那么會帶來什么問題?

    如果頻繁的主動關閉連接,可能會產生大量 ,由于 的連接占用了一個句柄及少量內存(4K),那么就有可能會影響其他連接的建立,比如:

    出現 too many open files 異常..

    該如何解決:

    黑板:HTTP 協議里頭發現了的問題,于是在 HTTP 1.1 中定義了 用來支持連接的重用。

    問題5. RST 是什么,為什么會出現

    RST 是一個特殊的標記,用來表示當前應該立即終止連接。以下這些情況都會產生RST:

    RST 機制有時候也會被利用,做一些端口的掃描,如下:

    -> 端口開啟,可接受SYN

    -> 端口關閉,響應RST

    小結

    原文只是想總結下 TCP 參數調優的幾個細節,沒想到TCP 牽扯出來的東西實在太多,光是一個簡單的握手、揮手流程就存在這么多的細節和坑。

    可以說為了保證數據傳輸的可靠性,早期的設計者確實考慮了太多的東西。當然,這也為上層的應用實現鋪平了道路。

    鑒于篇幅原因,只做了TCP 建鏈、拆鏈方面的介紹。關于數據的傳輸的一些細節,將在下篇文章梳理及分享。

    更多精彩內容,請滑至頂部點擊右上角關注小宅哦~

網站首頁   |    關于我們   |    公司新聞   |    產品方案   |    用戶案例   |    售后服務   |    合作伙伴   |    人才招聘   |   

友情鏈接: 餐飲加盟

地址:北京市海淀區    電話:010-     郵箱:@126.com

備案號:冀ICP備2024067069號-3 北京科技有限公司版權所有