chinese直男口爆体育生外卖, 99久久er热在这里只有精品99, 又色又爽又黄18禁美女裸身无遮挡, gogogo高清免费观看日本电视,私密按摩师高清版在线,人妻视频毛茸茸,91论坛 兴趣闲谈,欧美 亚洲 精品 8区,国产精品久久久久精品免费

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

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

3天內(nèi)不再提示

tcp數(shù)據(jù)包接口封裝的介紹

FPGA之家 ? 來源:CSDN ? 作者:hasaki_code ? 2021-03-22 09:39 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

TCP報文格式

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

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

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

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

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

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

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

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

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

6、窗口大小字段可看作捎帶的另一個例子,窗口通告可以附加在任何報文段中發(fā)送。在TCP發(fā)送一個報文時,可在窗口字段中填寫相應值以通知對方自己的可用緩沖區(qū)大?。ㄒ宰止?jié)為單位),報文接收方需要根據(jù)這個值來調(diào)整發(fā)送窗口的大小。這個字段是16bit的,所以通告窗口的最大值為65535字節(jié)。窗口字段是實現(xiàn)流量控制的關鍵字段,當接收方向發(fā)送方通知一個大小為0的窗口時,將完全阻止發(fā)送方的數(shù)據(jù)發(fā)送

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

構造TCP報文段

接下來,我們使用結(jié)構體來定義TCP報文,該結(jié)構體定義在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));

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

tcp報文發(fā)送接口

tcp數(shù)據(jù)的發(fā)送接口tcp_transmit_skb,會在tcp建立可靠連接和數(shù)據(jù)發(fā)送時被多次調(diào)用,如三次握手、write()、read()等。在level-ip中,該接口函數(shù)保存在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行:自己發(fā)送的數(shù)據(jù)的起始序號

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

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

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

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

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

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

第16行:保留位

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

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

第18行:校驗和設置為0

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

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

tcp接收接口

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

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數(shù)據(jù)包的data區(qū)域中讀取tcp數(shù)據(jù)信息

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

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

第20行:獲取該結(jié)構體的讀寫鎖

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

總結(jié)

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

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

原文標題:level-ip之tcp數(shù)據(jù)包接口封裝

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

責任編輯:haq

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學習之用,如有內(nèi)容侵權或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴

原文標題:level-ip之tcp數(shù)據(jù)包接口封裝

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

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關推薦
    熱點推薦

    MIMXRT1189奇數(shù)長度UDP數(shù)據(jù)包的最后一個字節(jié)出現(xiàn)問題,為什么?如何解決?

    我遇到了一個問題,即奇數(shù)長度 UDP 數(shù)據(jù)包的最后一個字節(jié)無法通過線路正確發(fā)送。最后一個字節(jié)似乎是未初始化或過時的數(shù)據(jù)。如果我將 UDP 數(shù)據(jù)包填充到偶數(shù)長度(2 字節(jié)綁定),則數(shù)據(jù)
    發(fā)表于 04-17 07:47

    CW32R030可以兼容BLE及XN297L數(shù)據(jù)包,請問這個XN297L數(shù)據(jù)包是什么?

    CW32R030可以兼容BLE及XN297L數(shù)據(jù)包,請問這個XN297L數(shù)據(jù)包是什么?
    發(fā)表于 01-20 06:37

    bk3633 usb 設備如何讀取主機向端點0 發(fā)送數(shù)據(jù)包

    bk3633 usb 設備如何讀取主機向端點0 發(fā)送數(shù)據(jù)包
    發(fā)表于 12-30 13:03

    TCP和UDP的區(qū)別

    花了非常多的功夫保證連接的可靠,這個可靠性體現(xiàn)在哪些方面呢?一個是有狀態(tài),另一個是可控制。 TCP 會精準記錄哪些數(shù)據(jù)發(fā)送了,哪些數(shù)據(jù)被對方接收了,哪些沒有被接收到,而且保證數(shù)據(jù)包
    發(fā)表于 12-09 07:24

    以太網(wǎng)通訊在FPGA上的實現(xiàn)

    數(shù)據(jù)量達到幾十,甚至成百上千個字節(jié)。下圖為以太網(wǎng)通過UDP傳輸單數(shù)據(jù)的格式,可以看出,以太網(wǎng)的數(shù)據(jù)包就是對各層協(xié)議的逐層封裝來實現(xiàn)
    發(fā)表于 10-30 07:45

    串行通信接口的結(jié)構和功能

    串口通訊的數(shù)據(jù)包由發(fā)送設備通過自身的TXD接口傳輸?shù)浇邮赵O備的RXD接口。在串口通訊的協(xié)議層中,規(guī)定了數(shù)據(jù)包的內(nèi)容,它由啟始位、主體數(shù)據(jù)、校
    的頭像 發(fā)表于 10-17 09:39 ?4162次閱讀
    串行通信<b class='flag-5'>接口</b>的結(jié)構和功能

    串口DMA接收數(shù)據(jù)包丟失怎么解決?

    RTT串口DMA接收數(shù)據(jù),超過緩沖區(qū)后為什么會吞掉一個數(shù)據(jù)包呢,不能每次處理完后清除緩沖區(qū)數(shù)據(jù)嗎,感覺接收的數(shù)據(jù)是累計的,累計滿之后會重新覆蓋,在最后一個
    發(fā)表于 09-29 07:50

    GD32F470+LWIP TCP偶爾丟怎么解決?

    的重發(fā)機制。 因此認為是校驗和之類的原因校驗失敗丟。 開啟了交換機端口鏡像,監(jiān)聽tcp到交換機后的數(shù)據(jù)流量,發(fā)現(xiàn)兩次上位機發(fā)送給板子出問題的tcp
    發(fā)表于 09-29 06:43

    嵌入式接口通識知識之MIPI接口

    工作原理MIPI DSI的接口示意圖大致如下圖所示:MIPI DSI 以串行的方式發(fā)送指令或者圖像信息給外設(即液晶,通常來說是液晶IC),也可以外設中讀取狀態(tài)信息,以獨立的通信協(xié)議,包括數(shù)據(jù)包格式
    發(fā)表于 08-29 15:50

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

    DCTCP與DCUDP 的登錄數(shù)據(jù)包和心跳數(shù)據(jù)包與服務器端是如何交互的?
    發(fā)表于 08-06 06:29

    CC\\-Link IE轉(zhuǎn)Modbus TCP:風電設備通信的“雙語模式”

    ,數(shù)據(jù)包丟失率高達5%,且偶爾出現(xiàn)通信中斷。 解決步驟: 1. 網(wǎng)關配置優(yōu)化:將Modbus TCP側(cè)的更新周期從1秒調(diào)整為500ms,并啟用網(wǎng)關的“心跳檢測”功能; 2. 地址沖突排查:檢查發(fā)現(xiàn)
    發(fā)表于 07-07 14:45

    RDMA簡介2之A技術優(yōu)勢分析

    數(shù)據(jù)包時,應用程序?qū)⒁獋鬏數(shù)?b class='flag-5'>數(shù)據(jù)拷貝到TCP/IP協(xié)議棧的BUFFER中,TCP/IP協(xié)議棧組后,再經(jīng)由驅(qū)動程序下發(fā)到網(wǎng)卡內(nèi)的BUFFER
    發(fā)表于 06-04 11:35

    藍牙數(shù)據(jù)通道空口數(shù)據(jù)包

    ? 與藍牙廣播相對應,藍牙數(shù)據(jù)包是另一種Bluetooth LE packet。藍牙數(shù)據(jù)包是藍牙數(shù)據(jù)信道空中的簡稱,表示空中
    發(fā)表于 06-03 10:51

    能否使用兩個 FX3 設備實現(xiàn) USB 數(shù)據(jù)包嗅探、插入和移除?

    能否使用兩個 FX3 設備實現(xiàn) USB 數(shù)據(jù)包嗅探、插入和移除?如果需要,除了兩個 FX3 設備外,還需要哪些硬件(如果有的話)?
    發(fā)表于 05-26 07:16

    更改最大數(shù)據(jù)包大小時無法識別USB設備如何解決?

    將生產(chǎn)者 EP 端點描述符中的最大數(shù)據(jù)包大小從 1024 字節(jié)更改為 512 字節(jié)時,無法識別 USB 設備。 請告知如何解決這個問題。
    發(fā)表于 05-20 08:13