在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

講一下TCP底層的收發過程

冬至子 ? 來源:周末程序猿 ? 作者:周末程序猿 ? 2023-08-01 17:24 ? 次閱讀

我們繼續探索高性能網絡編程,但是我覺得在談系統API之前可以先講一些Linux底層的收發包過程,如下這是一個簡單的socket編程代碼:

int main() {
    ... 

    fd = socket(AF_INET, SOCKET_STREAM, 0);
    bind(fd, ...);
    listen(fd, ...);

    // 如何建立連接
    ...
    afd = accept(fd, ...);

    // 如何接收數據
    ...
    read(afd, ...);

    // 如何發送數據
    ...
    send(afd, ...);

    // 如何關閉連接
    ...
    close(fd);
    ...
}

第一部分:如何建立連接

圖片

從上一篇文章我們介紹了網絡協議,我們知道TCP/IP協議族劃分了應用層、TCP傳輸層、IP網絡層、鏈路層(以太層驅動)。

如上圖看應用層,通常在網絡編程中我們需要調用accept的API建立TCP連接,那TCP如何做的呢?

圖片

從上圖的流程可以看到:
(1)client端發起TCP握手,發送syn包;
(2)內核收到包以后先將當前連接的信息插入到網絡的SYN隊列;
(3)插入成功后會返回握手確認(SYN+ACK);
(4)client端如果繼續完成TCP握手,回復ACK確認;
(5)內核會將TCP握手完成的包,先將對應的連接信息從SYN隊列取出;
(6)將連接信息丟入到ACCEPT隊列;
(7)應用層sever通過系統調用accept就能拿到這個連接,整個網絡套接字連接完成;

那基于這個圖,我想問問讀者這里會有什么問題么?
細心的讀者應該可以看出:
1、這里有兩個隊列,必然會有滿的情況,那如果遇到這種情況內核是怎么處理的呢?

(1)如果SYN隊列滿了,內核就會丟棄連接;
(2)如果ACCEPT隊列滿了,那內核不會繼續將SYN隊列的連接丟到ACCEPT隊列,如果SYN隊列足夠大,client端后續收發包就會超時;
(3)如果SYN隊列滿了,就會和(1)一樣丟棄連接;

2、如何控制SYN隊列和ACCEPT隊列的大小?

(1)內核2.2版本之前通過listen的backlog可以設置SYN隊列(半連接狀態SYN_REVD)和ACCEPT隊列(完全連接狀態ESTABLISHED)的上限;
(2)內核2.2版本以后backlog只是表示ACCEPT隊列上限,SYN隊列的上限可以通過/proc/sys/net/ipv4/tcp_max_syn_backlog設置;

3、server端通過accept一直等,豈不是會卡住收包的線程?

在linux網絡編程中我們都會追求高性能,accept如果卡住接收線程,性能會上不去,所以socket編程中就會有阻塞和非阻塞模式。
(1)阻塞模式下的accept就會卡住,當前線程什么事情都干不了;
(2)非阻塞模式下,可以通過輪詢accept去處理其他的事情,如果返回EAGAIN,就是ACCEPT隊列為空,如果返回連接信息,就是可以處理當前連接;

第二部分:接收數據

圖片

(1)當網卡接收到報文并判斷為TCP協議后,將會調用到內核的tcp_v4_rcv方法,如果數據按順序收到S1數據包,則直接插入receive隊列中;
(2)當收到了S3數據包,在第1步結束后,應該收到S2序號,但是報文是亂序進來的,則將S3插入out_of_order隊列(這個隊列存儲亂序報文);
(3)接下來收到S2數據包,如第1步直接進入receive隊列,由于此時out_of_order隊列不像第1步是空的,所以引發了接來的第4步;
(4)每次向receive隊列插入報文時都會檢查out_of_order隊列,如果遇到期待的序號S3,則從out_of_order隊列摘除,寫入到receive隊列;
(5)現在應用程序開始調用recv方法;
(6)經過層層封裝調用,接收TCP消息最終會走到tcp_recvmsg方法;
(7)現在需要拷貝數據從內核態到用戶態,如果receive隊列為空,會先檢查SO_RCVLOWAT這個閥值(0表示收到指定的數據返回,1表示只要讀取到數據就返回,系統默認是1),如果已經拷貝的字節數到現在還小于它,那么可能導致進程會休眠,等待拷貝更多的數據;
(8)將數據從內核態拷貝到用戶態,recv返回拷貝數據的大小;
(9)為了選擇降低網絡包延時或者提升吞吐量,系統提供了tcp_low_latency參數,如果為0值,用戶暫時沒有讀數據則數據包進入prequeue隊列,提升吞吐量,否則不使用prequeue隊列,進入tcp_v4_do_rcv,降低延時;

第三部分:發送數據

圖片

(1)假設調用send方法來發送大于一個MSS(比如2K)的數據;
(2)內核調用tcp_sendmsg,實現復制數據,寫入隊列和組裝tcp協議頭;
(3)在調用tcp_sendmsg先需要在內核獲取skb,將用戶態數據拷貝到內核態,內核真正執行報文的發送,與send方法的調用并不是同步的,即send方法返回成功,也不一定把IP報文都發送到網絡中了。因此,需要把用戶需要發送的用戶態內存中的數據,拷貝到內核態內存中,不依賴于用戶態內存,也使得進程可以快速釋放發送數據占用的用戶態內存。但這個拷貝操作并不是簡單的復制,而是把待發送數據,按照MSS來劃分成多個盡量達到MSS大小的分片報文段,復制到內核中的sk_buff結構來存放;
(4)將數據拷貝到發送隊列中tcp_write_queue
(5)調用tcp_push發送數據到IP層,這里主要滑動窗口,慢啟動,擁塞窗口的控制和判斷是否使用Nagle算法合并小報文(上一篇已經有介紹);
(6)組裝IP報文頭,通過經過iptables或者tcpdump等netfilter模塊過濾,將數據交給鄰居子系統(主要功能是查找需要發送的MAC地址,發送arp請求,封裝MAC頭等);
(7)調用網卡驅動程序將數據發送出去;

第四部分:關閉連接

關閉連接就是TCP揮手過程,我們都知道TCP連接是一種可靠的連接,那如何才能完整可靠的完成關閉連接呢?linux系統提供了兩個函數:

  • close對應tcp_close方法,通過減少socket的引用次數實現關閉,僅當引用計數為0時才會觸發tcp_close;
    圖片
  • shutdown對應tcp_shutdown方法,不關心socket被引用次數,直接關閉對應的連接;
    圖片

(1)shutdown可攜帶一個參數,取值有3個,分別意味著:只關閉讀、只關閉寫、同時關閉讀寫;

(2)若shutdown的是半打開的連接,則發出RST來關閉連接;
(3)若shutdown的是正常連接,那么關閉讀其實與對端是沒有關系的;
(4)若參數中有標志位為關閉寫,那么下面做的事與close是一致的,發出FIN包,告訴對方本機不會再發消息了;

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 驅動器
    +關注

    關注

    53

    文章

    8255

    瀏覽量

    146517
  • 連接器
    +關注

    關注

    98

    文章

    14550

    瀏覽量

    136678
  • Linux系統
    +關注

    關注

    4

    文章

    594

    瀏覽量

    27418
  • RST
    RST
    +關注

    關注

    0

    文章

    31

    瀏覽量

    7402
  • TCP通信
    +關注

    關注

    0

    文章

    146

    瀏覽量

    4228
收藏 人收藏

    評論

    相關推薦

    一講TCP三次握手和四次揮手

    如果你學過網絡基礎知識,那么你定對TCP三次握手不陌生。今天我想用通俗的話來給大家一講TCP三次握手和四次揮手。畢竟,這個知識點在面試時
    的頭像 發表于 02-03 10:43 ?2729次閱讀
    <b class='flag-5'>講</b><b class='flag-5'>一講</b>的<b class='flag-5'>TCP</b>三次握手和四次揮手

    哪位高手能給一下預分頻的作用 或者有資料的分享一下

    哪位高手能給一下預分頻的作用或者有資料的分享一下先行謝過
    發表于 02-10 22:42

    網絡子系統在鏈路層的收發過程剖析

    網絡子系統在鏈路層的收發過程剖析
    發表于 08-15 17:58

    求大神給一下電機驅動原理

    求大神給一下電機驅動原理越詳細越好,感謝
    發表于 02-01 21:02

    MCBSP的收發過程是如何運行的

    MCBSP_rrdy(hMcbsp)為0時,表明DRR中的數據已經被讀取,x = MCBSP_read(hMcbsp)語句如何理解?整個MCBSP的收發過程是如何運行的,我理解反了?謝謝,請高手指導指導。
    發表于 05-25 08:44

    個嵌入式系統的開發過程有哪些步驟?

    以MVB為例,解答一下嵌入式系統的開發過程有哪些步驟?
    發表于 04-27 06:36

    求大神詳細介紹一下FPGA嵌入式系統開發過程中的XBD文件設計

    求大神詳細介紹一下FPGA嵌入式系統開發過程中的XBD文件設計
    發表于 05-06 08:19

    一下在單片機開發過程中使用過的幾種調試方案

    邊運行邊修改參數呢?調試的方法有多種,在這就來分別談一下我在開發過程中使用過的幾種調試方案。這里的調試方案也是種交互方案,但此方案不是為了交互而設計,重在快速地搭建、方便地使用、高
    發表于 01-14 08:25

    nodemcu的開發過程是怎樣的

    關于nodemcu的點點滴滴##### 網絡協議之前,我覺得應該把nodemcu的開發過程梳理遍,再說下自己調試遇到的問題。- 因為自己也是剛接觸lua和esp12,理解上可能會有很多錯誤,希望
    發表于 02-16 06:25

    簡單敘述一下STM32CubeIDE的開發過程

    STM32的資源是怎樣進行配置的?STM32CubeIDE的開發過程是怎樣的?
    發表于 02-24 06:28

    資源約束產品開發過程仿真模型

    提出考慮資源約束的產品開發過程仿真模型。該模型考慮產品開發過程中的返工迭代以及資源約束,根據任務信息控制能力確定任務資源分配的優先級,相對于Cooper 提出的資源分
    發表于 04-16 11:36 ?16次下載

    掌握串口通信協議的收發過程

    現在我們要做個實驗,將個字節從51單片機發送到電腦串口調試助手上。這個實驗的目的是為了掌握串口通信協議的收發過程
    的頭像 發表于 12-22 10:02 ?7.9w次閱讀
    掌握串口通信協議的<b class='flag-5'>收發過程</b>

    錫膏廠家一下助焊劑的危害有哪些?

    會成本比較高,這是相對應的,所以大家焊接過程種還是要注意,下面佳金源錫膏廠家一下有哪些危害:助焊劑的危害有:般情況,如果技術工人接觸到
    的頭像 發表于 01-10 09:30 ?1683次閱讀
    錫膏廠家<b class='flag-5'>講</b><b class='flag-5'>一下</b>助焊劑的危害有哪些?

    Linux TCP底層收發過程講解

    我們繼續探索高性能網絡編程,但是我覺得在談系統API之前可以先講些Linux底層收發過程
    發表于 08-08 15:42 ?451次閱讀
    Linux <b class='flag-5'>TCP</b><b class='flag-5'>底層</b>的<b class='flag-5'>收發過程</b>講解

    ASIC芯片開發過程

    電子發燒友網站提供《ASIC芯片開發過程.ppt》資料免費下載
    發表于 12-25 10:04 ?1次下載
    主站蜘蛛池模板: 日韩免费| 久久中文字幕综合婷婷| 美女扒开内裤让男人桶| 婷婷午夜激情| 亚洲最大成人在线| 夜夜爽夜夜操| 天堂网最新版中文| 69美女poren 18| www.亚洲欧美| 免费特黄一区二区三区视频一| 女人张开腿让男人做爽爽| 永久免费在线播放| 午夜性刺激免费视频观看不卡专区| 午夜国产片| 久久久黄色片| 看免费一级片| 高清国产在线| 男女在线免费视频| 亚洲综合色婷婷| 日韩一级片免费看| 好硬好大好爽女房东在线观看| 99精品久久久久久久婷婷| 视频在线观看免费| 午夜色大片在线观看| 精品一区亚洲| 国产精品久久久久久久久kt| 激情理论| 色优久久| 五月婷婷亚洲综合| 亚洲人成在线精品| 亚洲日本精品| 狠狠色综合色综合网络| 3344免费播放观看视频| 天天躁狠狠躁夜夜躁2021| 羞羞色男人的天堂伊人久久| 色妹子在线| 国产欧美色图| 欧美成人午夜片一一在线观看| 免费高清成人啪啪网站| 一级毛片真人免费观看| 欧美日韩无|