衡阳派盒市场营销有限公司

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

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

3天內不再提示

tcp數據包接口封裝的介紹

FPGA之家 ? 來源:CSDN ? 作者:hasaki_code ? 2021-03-22 09:39 ? 次閱讀

TCP報文格式

TCP協議有著自己的數據包格式,這里把TCP的數據包稱為報文段(segment),TCP報文段封裝在IP數據報中發送,TCP報文段由TCP首部和TCP數據區組成,首部區域包含了連接建立與斷開、數據確認、窗口大小通告、數據發送相關的所有標志和控制信息。如下圖:

1c804092-8924-11eb-8b86-12bb97331649.png

首部的大小為20~60字節,在沒有任何選項的情況下,首部大小為20字節,與不含選項字段的IP報首部大小相同。TCP報文中的數據部分可以為空,例如在一個連接建立或斷開時,雙方交換的報文段僅有TCP首部;又如當一方沒有任何數據需要發送,則它需要使用不包含任何數據的報文段來發送確認信息。

1、源端口號和目的端口號兩個字段用于標識發送端和接收端應用進程分別綁定的端口號。這兩個值加上IP數據報首部中的源IP地址和目的IP地址就能唯一確定一個TCP連接

2、32位序號字段標識了從TCP發送端到TCP接收端的數據字節編號,它的值為當前報文段中第一個數據的字節序號。在接收方,先計算出數據區數據的長度,然后使用首部中的序號字段,就能計算出報文最后一個字節數據的序號。當建立一個新連接時,握手報文首部中的SYN標志置1,此時,序號字段包含由發送方隨機選擇的初始序號ISN(Initial Sequence Number)。建立連接的報文(SYN)將占用一個數據編號,因此發送方隨后將要發送數據的第一個字節序號為ISN+1

3、32位確認序號只有ACK標志為1時才有效,它包含了本機所期望收到的下一個數據序號,確認常常和反向數據一起捎帶發送

4、4位首部長度指出了TCP首部的長度,以4字節為單位。需要這個值是因為選項字段的長度是可變的。由于這個字段有4bit,因此TCP最多有60字節的首部,如果沒有任何選項字段,首部長度應該為5(20字節)

5、在TCP首部中有6個標志bit,它們中的多個可同時被設置為1,它們告訴了接收端應該如何解釋報文的內容,比如一些報文段攜帶了確認信息、一些報文段攜帶了緊急數據、一些報文包含建立或關閉連接的請求。6個標志位的意義如下圖:

1d1e6826-8924-11eb-8b86-12bb97331649.png

6、窗口大小字段可看作捎帶的另一個例子,窗口通告可以附加在任何報文段中發送。在TCP發送一個報文時,可在窗口字段中填寫相應值以通知對方自己的可用緩沖區大?。ㄒ宰止潪閱挝唬瑘笪慕邮辗叫枰鶕@個值來調整發送窗口的大小。這個字段是16bit的,所以通告窗口的最大值為65535字節。窗口字段是實現流量控制的關鍵字段,當接收方向發送方通知一個大小為0的窗口時,將完全阻止發送方的數據發送

7、16位的緊急指針只有當緊急標志位URG置位時才有效,此時報文中包含了緊急數據,緊急數據始終放在報文段數據開始的地方,而緊急指針定義出了緊急數據在數據區中的結束處,用這個值加上序號字段值就得到了最后一個緊急數據的序號

構造TCP報文段

接下來,我們使用結構體來定義TCP報文,該結構體定義在level-ip的include/tcp.h文件中:

struct tcphdr {uint16_t sport;uint16_t dport;uint32_t seq;uint32_t ack_seq;uint8_t rsvd : 4;uint8_t hl : 4;uint8_t fin : 1,syn : 1,rst : 1,psh : 1,ack : 1,urg : 1,ece : 1,cwr : 1;uint16_t win;uint16_t csum;uint16_t urp;uint8_t data[];} __attribute__((packed));

這個結構體的成員變量,與我們剛才介紹的TCP報文格式的每個字段是一一對應的,這里不再重復解析。

tcp報文發送接口

tcp數據的發送接口tcp_transmit_skb,會在tcp建立可靠連接和數據發送時被多次調用,如三次握手、write()、read()等。在level-ip中,該接口函數保存在src cp_output.c文件中。如下圖:

static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, uint32_t seq){struct tcp_sock *tsk = tcp_sk(sk);struct tcb *tcb = &tsk-》tcb;struct tcphdr *thdr = tcp_hdr(skb);/* No options were previously set */if (thdr-》hl == 0) thdr-》hl = TCP_DOFFSET;skb_push(skb, thdr-》hl * 4);thdr-》sport = sk-》sport;thdr-》dport = sk-》dport;thdr-》seq = seq;thdr-》ack_seq = tcb-》rcv_nxt;thdr-》rsvd = 0;thdr-》win = tcb-》rcv_wnd;thdr-》csum = 0;thdr-》urp = 0;if (thdr-》hl 》 5) {tcp_write_options(tsk, thdr);}tcp_out_dbg(thdr, sk, skb);thdr-》sport = htons(thdr-》sport);thdr-》dport = htons(thdr-》dport);thdr-》seq = htonl(thdr-》seq);thdr-》ack_seq = htonl(thdr-》ack_seq);thdr-》win = htons(thdr-》win);thdr-》csum = htons(thdr-》csum);thdr-》urp = htons(thdr-》urp);thdr-》csum = tcp_v4_checksum(skb, htonl(sk-》saddr), htonl(sk-》daddr));return ip_output(sk, skb);}

第12行:設置源端口號

第13行:設置目標端口號

第14行:自己發送的數據的起始序號

第15行:通知對方期望接收的下一字節的序號

在IP協議中,會對每個數據報進行編號,而在TCP中沒有報文編號的概念,因為它的目標是數據流傳輸,數據流由連續的字節流組成,盡管在上層可能用各種各樣的數據結構和格式來描述數據,但在TCP看來,數據都是字節流。TCP把一個連接中的所有數據字節都進行了編號,當然兩個方向上的編號是彼此獨立的,編號的初始值由發送數據的一方隨機選取,編號取值是0~2^32-1,比如發送方選擇的起始編號為20,且將要發送的數據長度為800字節,那么字節編號將覆蓋20到819的范圍。當所有字節被編上號后,字節流會被分裝在若干個TCP報文中發送,此時TCP報文首部的字段能夠記錄它所運載數據的起始編號以及運載數據的長度。在接收端,可以根據這些信息對報文中數據進行排序和確認。例如,將上述的800字節放在三個報文段中來發送,前兩個報文段各裝載了300字節的數據,最后一個報文裝載了200字節的數據,則三個報文段攜帶的數據情況如下:

報文段1:起始序號:20,數據長度:300,序號范圍:20~319

報文段2:起始序號:320,數據長度:300,序號范圍:320~619

報文段3:起始序號:620,數據長度:200,序號范圍:620~819

接收方通過確認的機制來告訴發送方數據的接收狀況,這是通過向發送方返回一個確認號來完成的,確認號標識出自己期望接收到的下一個字節的編號,例如在上面的例子中,如果接收方接收到了報文段1,則它返回給發送方的確認號為320,表示自己期望收到數據編號為320的數據;確認號是累計的,即如果發送方接收到確認號的值為620,說明接收方已經正確接收了620編號以前的所有數據,接收方可能是在收到兩個報文段后才發送的一個確認;還有一種情況,如果接收方只收到報文段1和3,那么它返回的確認號仍然是320,確認號始終表示接收方期望的下一字節數據,盡管可能已有更高編號的數據被收到

第16行:保留位

第17行:設置滑動窗口大小

在數據發送端,所有數據流按照順序被組織在發送緩存中,什么時候發送數據以及發送的多少是由滑動窗口決定的,使用窗口滑動的概念可以達到很好的流量控制效果和擁塞控制效果。如下圖所示,滑動窗口可以看成定義在數據緩沖上的一個窗口,緩沖中存放了從應用程序傳遞過來的待發送數據,窗口能在緩沖上滑動,滑動窗口狀態決定了TCP能發送哪些數據。滑動窗口較大時, TCP可以在收到確認之前一次性地發送幾個報文段,這樣,可以使得網絡總是處于忙碌狀態,提高網絡的吞吐率。當發送窗口較小時,能夠被發送的報文很少,在極端情況下,當發送窗口為0時,沒有任何報文能被發送,減少報文的發送是進行擁塞控制的最直接手段。因此,流量控制和擁塞控制的本質在于對發送窗口的合理調節

第18行:校驗和設置為0

第19行:緊急指針設置為0,

TCP采用了緩沖機制來保證協議的高效性,在數據發送時,TCP內核將延遲小分組數據的交付,它將等待足夠長的時間,以期待接收更多的應用數據,最后再一起發送;在接收數據時,TCP首先是先將數據放在接收緩沖中,只有在應用程序準備就緒或者TCP協議認為時機恰當的時候,數據才會被交付給應用程序。上述緩沖機制是出于對網絡性能提升的考慮,但是它可能會妨礙某些應用程序的使用。例如,兩個應用程序進行交互式通信,一端應用程序打算把用戶鍵入的字符發送給另一端應用程序,并且期望對方立即響應。在這種情況下,TCP的數據收集與延遲發送、緩沖遞交會給用戶帶來很不好的體驗。為了滿足交互式應用場合的需求,TCP可以采用下面的方式解決這個問題。發送方應用程序向TCP傳遞數據時,請求推送(push)操作,這時,TCP協議不會等待發送緩沖區被填滿,而是直接將報文發送出去。同時,被推送出去的報文首部中推送位(PSH)將被置1,接收端在收到這類報文時,會盡快將數據遞交給應用程序,而不必緩沖更多的數據再遞交

tcp接收接口

tcp數據接收接口為tcp_in()函數。該函數在ip數據幀讀取接口ip_rcv()函數中調用。該函數保存在srcip_input.c文件中,我們來了解一下這個函數,如下圖:

void tcp_in(struct sk_buff *skb){struct sock *sk;struct iphdr *iph;struct tcphdr *th;iph = ip_hdr(skb);th = (struct tcphdr*) iph-》data;tcp_init_segment(th, iph, skb);sk = inet_lookup(skb, th-》sport, th-》dport);if (sk == NULL) {print_err(“No TCP socket for sport %d dport %d ”,th-》sport, th-》dport);free_skb(skb);return;}socket_wr_acquire(sk-》sock);tcp_in_dbg(th, sk, skb);/* if (tcp_checksum(iph, th) != 0) { *//* goto discard; *//* } */tcp_input_state(sk, th, skb);socket_release(sk-》sock);}

第7行:從sk_buff中讀取ip首部信息

第8行:從ip數據包的data區域中讀取tcp數據信息

第10行:進行關鍵字段的大小端變換和計算應答序號等

第12行:根據通信端口,查找管理該次tcp連接的結構體sock

第20行:獲取該結構體的讀寫鎖

第26行:數據遞交給tcp_input_state()函數處理,該函數會進行tcp通信狀態的變化,以及獲取把整理好的有序報文遞交給應用程序。

總結

在對可靠性要求很高的場合下,使用TCP提供的傳輸性能是很合適的,TCP將兩個進程間傳遞的數據看作數據流的形式,兩個先后發出的TCP報文雖然在網絡中也是互不相關的傳輸,但是它們攜帶的數據之間卻具有關聯關系,因為TCP給傳輸的每個字節數據一個唯一的編號。在接收端,所有數據將按照編號被順序組織起來,當所有數據接收成功后,TCP才把數據遞交給應用層。應用層不必擔心報文的亂序、重復、丟失等問題,TCP采用正面確認以及超時重傳等機制保證數據流能全部正確到達。

但是,我們這篇文章還沒涉及到這部分的內容,但是我們已經找到分析的突破口,那就是上面所提到的tcp_input_state()函數,以后我們將在該函數里面剖析tcp種種可靠性機制。

原文標題:level-ip之tcp數據包接口封裝

文章出處:【微信公眾號:FPGA之家】歡迎添加關注!文章轉載請注明出處。

責任編輯:haq

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

    關注

    8

    文章

    7145

    瀏覽量

    89582

原文標題:level-ip之tcp數據包接口封裝

文章出處:【微信號:zhuyandz,微信公眾號:FPGA之家】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    調試TCP協議連接的常用工具

    Wireshark 是一個開源的網絡協議分析器,它可以捕獲和分析網絡上的數據包。Wireshark 支持多種協議,包括TCP/IP、HTTP、FTP等,是調試TCP連接的首選工具。 功能特點
    的頭像 發表于 01-22 09:59 ?192次閱讀

    I2C總線數據包結構詳解

    。以下是I2C總線數據包結構的詳解: 一、I2C總線數據包的基本組成 I2C總線上的數據傳輸以數據包為單位進行,每個數據包包含起始信號、設備
    的頭像 發表于 01-17 15:46 ?180次閱讀

    mtu配置步驟詳解 mtu與數據包丟失的關系

    MTU(Maximum Transmission Unit)即最大傳輸單元,是指一種通信協議的某一層上面所能通過的最大數據報大小,單位是字節。MTU配置步驟及其與數據包丟失的關系如下: MTU配置
    的頭像 發表于 12-16 14:33 ?1115次閱讀

    艾體寶干貨 OIDA之四:掌握數據包分析-分析的藝術

    本文是OIDA方法系列的最后一部分,重點介紹數據包分析的“分析”階段。這一最后階段將剖析階段的精煉數據轉化為可操作的見解,使網絡管理員和安全專業人員能夠解決問題、優化性能并增強安全性。分析是實現
    的頭像 發表于 09-24 11:47 ?245次閱讀
    艾體寶干貨 OIDA之四:掌握<b class='flag-5'>數據包</b>分析-分析的藝術

    請問DCTCP與DCUDP 的登錄數據包和心跳數據包與服務器端是如何交互的?

    DCTCP與DCUDP的登錄數據包和心跳數據包與服務器端是如何交互的?
    發表于 07-25 06:37

    使用AT SAVETRANSLINK時UDP數據包丟失怎么解決?

    Android 發送一個小 UDP 數據包(5 字節)。這個小數據包被我的微控制器在UART上接收到。微控制器將更大的數據包(可變長度,約 100 字節)發送回 UART。ESP在UART上接
    發表于 07-18 07:17

    能否在ESP結束之前通過串行端口停止傳入的UDP數據包的傳輸以解析下一個UDP數據包?

    我正在做一個artnet節點, 它收到幾個 UDP 廣播數據包,工作正常,但是: 其中一些必須使用,其中一些必須丟棄, mi問題是:所有傳入的數據包都出現在帶有IPD命令的串行端口上, 并且我需要
    發表于 07-16 06:18

    請問如何使用AT CIPSEND或AT CIPSENDBUF發送多個數據包

    我可以使用 AT CIPSEND 發送單個數據包。但是我必須發送一系列二進制數據包。如何使用AT CISEND或AT CIPSENDBUF發送多個數據包,什么是正確的算法? 到目前為止,我嘗試
    發表于 07-15 07:37

    TCP傳輸大量數據時丟失數據的原因?

    TCP用于傳輸大量數據時,要找到數據丟失的地方,當TCP傳輸大量數據時,數據包丟失,
    發表于 07-12 15:03

    ESP32-C3在SPI-AT模式下進行數據透傳,最后一個數據包數據偶爾會出現錯誤,為什么?

    目前采用SPI-AT的方式在兩個硬件板之間進行數據的無線傳輸,一個作為AP開啟TCP服務器,一個作為STA連接到對應的服務器,傳輸的數據量為3000000字節,在測試的過程中偶爾會出現數據
    發表于 06-26 06:07

    在AN65974中短數據包和零長數據包是什么意思?

    在 AN65974 中,短數據包和零長數據包是什么意思? 非常感謝!
    發表于 05-30 07:41

    如何在AIROC GUI上獲取良好數據包和總數據包

    使用 IQxel-MW LifePoint 作為發生器并發送波形BT_1DH5_00001111_Fs80M.iqvsg,但無法在 AIROC 工具中接收數據包。 以下是從 IQxel 發送
    發表于 05-22 06:39

    請問高端網絡芯片如何處理數據包呢?

    隨著網絡芯片帶寬的持續提升,其內部數據包處理單元的工作負載也隨之增加。然而,如果處理單元無法與網絡接口的傳入速率相匹配,將無法及時處理數據包,這不僅會導致數據包隨機丟失,更會降低網絡的
    的頭像 發表于 04-02 16:36 ?701次閱讀
    請問高端網絡芯片如何處理<b class='flag-5'>數據包</b>呢?

    STM32H7接收數據包異常,一接收的數據出現兩發送的內容怎么解決?

    );__HAL_UART_DISABLE_IT( huart1, DMA_IT_HT); 2、發送數據包1
    發表于 03-08 08:05

    DPDK在AI驅動的高效數據包處理應用

    傳統的數據包處理方式是數據包先到內核最后再到用戶層進行處理。這種方式會增加額外的延遲和CPU開銷,嚴重影響數據包處理的性能。 DPDK 繞過內核,在用戶空間中實現快速數據包處理。
    的頭像 發表于 02-25 11:28 ?1061次閱讀
    DPDK在AI驅動的高效<b class='flag-5'>數據包</b>處理應用
    太阳城假日酒店| 地理风水24山72局杨公水法| 澳门百家乐官网战法| 正品百家乐官网电话| 玩百家乐官网去哪个娱乐城最安全 | 百家乐官网平注资讯| 百家乐在线小游戏| 真人百家乐游戏软件| 大发888信誉net| 牛牛现金棋牌| k7百家乐官网最小投注| 百家乐官网网上娱乐场开户注册 | 百家乐官网赌场在线娱乐| 最可信百家乐官网娱乐城| 蓝盾百家乐网址| 南通热线棋牌中心| 赌博百家乐官网作弊法| 赌神网百家乐官网2| 百家乐扑克投注赢钱法| 太阳城娱乐小郭| 漠河县| 筹码百家乐官网的玩法技巧和规则 | 在线百家乐官网电脑| 百家乐专用台布| 德州扑克高牌| 澳门百家乐官网大揭密| 百家乐连线游戏下载| 全讯网六仔开奖| 崇文区| 做生意风水关键吗| 大发888娱乐城大发888大发网| 大发888 dafa888 gzsums| 百家乐官网乐城皇冠| 福布斯百家乐官网的玩法技巧和规则| 网上的百家乐官网怎么才能| 百家乐官网赌场合作| 金鼎百家乐局部算牌法| 任你博| 大赢家即时比分| 飞天百家乐官网的玩法技巧和规则| 百家乐开户送彩网址|