日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

lwip之数据收发流程_1

發(fā)布時(shí)間:2025/4/5 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 lwip之数据收发流程_1 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
lwip從邏輯上看也是分為4層:鏈路層、網(wǎng)絡(luò)層(IP、ARP、(ICMP、IGMP這兩個(gè)協(xié)議是網(wǎng)絡(luò)層的補(bǔ)充協(xié)議,并不嚴(yán)格屬于網(wǎng)絡(luò)層))、傳輸層(TCP、UDP)、應(yīng)用層,基本等同TCP/IP,只是各層之間可以進(jìn)行交叉存取,沒有嚴(yán)格劃分。 協(xié)議匯總:1. ARP協(xié)議:根據(jù)IP地址獲取物理地址MAC的一個(gè)TCP/IP協(xié)議 一個(gè)典型的lwip系統(tǒng)包含3個(gè)進(jìn)程:首先是上層應(yīng)用程序進(jìn)程,然后是lwip協(xié)議棧進(jìn)程,最后是底層硬件數(shù)據(jù)包接收進(jìn)程動(dòng)態(tài)內(nèi)存管理:采用ucos-ii內(nèi)存管理系統(tǒng),即申請(qǐng)一塊內(nèi)存,分割成整數(shù)個(gè)大小相同的內(nèi)存塊 一.?? ?鏈路層當(dāng)主機(jī)A要與主機(jī)B通信時(shí),ARP協(xié)議可以將主機(jī)B的IP地址解析成主機(jī)B的MAC地址,工作流程如下:?? ?第一步:主機(jī)A先檢查自己的ARP緩沖,看是否存在主機(jī)B匹配的MAC地址,如果沒有,就會(huì)向外廣播一個(gè)ARP請(qǐng)求包第二步:其他主機(jī)收到后,發(fā)現(xiàn)請(qǐng)求的IP地址與自己的IP地址不匹配,則丟棄ARP請(qǐng)求第三步:主機(jī)B確定ARP請(qǐng)求中的IP地址與自己的IP地址匹配,則將主機(jī)A的IP地址和MAC地址映射到本地ARP緩存中第四步:主機(jī)B將包含其MAC地址的ARP回復(fù)發(fā)回給主機(jī)A第五步:主機(jī)A收到從主機(jī)B發(fā)來的ARP回復(fù)時(shí),會(huì)將主機(jī)B的IP地址和MAC地址映射更新到本地ARP緩存中。主機(jī)B的MAC地址一旦確定,主機(jī)A就可以向主機(jī)B發(fā)送IP通信了連接鏈路層和網(wǎng)絡(luò)層的紐帶:以太網(wǎng)數(shù)據(jù)包接收進(jìn)程tcpip_threadstatic void tcpip_thread(void *arg){struct tcpip_msg *msg;?? ??? ?// 消息來自于網(wǎng)卡中斷while(1){// 該任務(wù)阻塞在這里接收要處理的消息,當(dāng)有數(shù)據(jù)包到來時(shí),網(wǎng)卡芯片中斷函數(shù)接收數(shù)據(jù),并post消息,中斷退出后,該任務(wù)獲取消息sys_timeouts_mbox_fetch(&mbox, (void **)&msg);?? ?// 判斷本條消息的類型,只關(guān)注數(shù)據(jù)包消息TCPIP_MSG_INPKTswitch (msg->type){case TCPIP_MSG_INPKT:?? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ?// 數(shù)據(jù)包消息if(msg->msg.inp.netif->flags & (NETIF_FLAG_ETHARP | NETIF_FLAG_ETHERNET))ethernet_input(msg->msg.inp.p,msg->msg.inp.netif);?? ?// 如果支持ARP,先進(jìn)行ARP處理,再判斷是否遞交IP層,對(duì)于IP數(shù)據(jù)包,這里2個(gè)選擇最終都要調(diào)用ip_input進(jìn)入IP層elseip_input(msg->msg.inp.p, msg->msg.inp.netif);?? ??? ??? ?// 否則直接遞交IP層,ip_input為IP層主要函數(shù),解析見下文,這里直接調(diào)用ip_input存在問題,有誤,需要先以太網(wǎng)數(shù)據(jù)包指針,使掠過包頭,指向IP協(xié)議包頭memp_free(MEMP_TCPIP_MSG_INPKT, msg);?? ??? ??? ??? ??? ??? ?// 釋放消息內(nèi)存break;case TCPIP_MSG_TIMEOUT:?? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ?// 超時(shí)消息sys_timeout(msg->msg.tmo.msecs, msg->msg.tmo.h, msg->msg.tmo.arg);memp_free(MEMP_TCPIP_MSG_API, msg);break;default:break;}}}err_t ethernet_input(struct pbuf *p,struct netif *netif){struct eth_hdr *ethhdr;?? ??? ??? ??? ??? ?// 以太網(wǎng)數(shù)據(jù)包頭結(jié)構(gòu)體u16_t type;s16_t ip_hdr_offset = SIZEOF_ETH_HDR;?? ?// 包頭固定值14字節(jié)ethhdr = (eth_hdr *)p->payload;type = htons(ethhdr->type);switch(type){case ETHTYPE_IP:?? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ?// IP數(shù)據(jù)包etharp_ip_input(netif,p);?? ??? ??? ??? ??? ??? ??? ??? ??? ?// 使用收到的IP包更新ARP緩存表,詳見《lwip之ARP協(xié)議》pbuf_header(p, -ip_hdr_offset);?? ??? ??? ??? ??? ??? ??? ??? ?// 調(diào)整以太網(wǎng)數(shù)據(jù)包指針,使掠過包頭,指向IP協(xié)議包頭ip_input(p,netif);?? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ?// 提交IP層,ip_input為IP層主要函數(shù),解析見下文case ETHTYPE_ARP:?? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ?// ARP數(shù)據(jù)包etharp_arp_input(netif,(struct eth_addr *)netif->hwaddr,p);?? ?// ARP數(shù)據(jù)包處理,第二個(gè)形參是本機(jī)MAC,詳見《lwip之ARP協(xié)議》break;default:break;}}注:消息結(jié)構(gòu)體struct tcpip_msg {enum tcpip_msg_type type;?? ??? ??? ??? ?// 本條消息的類型:TCPIP_MSG_INPKT - 數(shù)據(jù)包消息,TCPIP_MSG_TIMEOUT - 超時(shí)消息sys_sem_t *sem;?? ??? ??? ??? ??? ??? ??? ?// 事件控制塊ECBunion{struct api_msg *apimsg;struct netifapi_msg *netifapimsg;struct {struct pbuf *p;struct netif *netif;} inp;?? ??? ??? ??? ??? ??? ??? ??? ?// inp結(jié)構(gòu)體最重要,內(nèi)含數(shù)據(jù)包內(nèi)容結(jié)構(gòu)、網(wǎng)絡(luò)接口結(jié)構(gòu)struct {tcpip_callback_fn function;void *ctx;} cb;struct {u32_t msecs;sys_timeout_handler h;void *arg;} tmo;}msg;}----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------?? ? 二. 網(wǎng)絡(luò)層lwip使用一個(gè)ip_hdr的結(jié)構(gòu)體來描述IP協(xié)議包頭:struct ip_hdr{u16_t _v_hl_tos;?? ?// 包含4位版本號(hào)(IPv4 - 4,IPv6 - 6)、4位IP包頭長(zhǎng)(通常為5*4,即本結(jié)構(gòu)體大小)、8位服務(wù)類型u16_t _len;?? ??? ??? ?// 整個(gè)IP數(shù)據(jù)包長(zhǎng)度u16_t _id;?? ??? ??? ?// 16位標(biāo)識(shí)用于標(biāo)識(shí)IP層發(fā)出的每一份IP報(bào)文,自增u16_t _offset;?? ??? ?// 包含3位標(biāo)志和13位片偏移,IP數(shù)據(jù)包分片時(shí)使用u8_t _ttl;?? ??? ??? ?// TTL描述該IP數(shù)據(jù)包最多能被轉(zhuǎn)發(fā)的次數(shù),自減u8_t _proto;?? ??? ?// 協(xié)議字段用于描述該IP數(shù)據(jù)包的上層協(xié)議,0x01 - ICMP,0x02 - IGMP,0x06 - TCP,0x17 - UDPu16_t _chksum;?? ??? ?// 16位的IP首部校驗(yàn)和ip_addr_p_t src;?? ?// 源IPip_addr_p_t dest;?? ?// 目的IP}ip_input為IP層主干函數(shù),完成了IP層數(shù)據(jù)包處理(核心工作就是IP地址匹配;得到完整數(shù)據(jù)包),然后將合適的數(shù)據(jù)包提交給上層,這里的p->payload已經(jīng)越過了14字節(jié)包頭,指向了IP頭err_t ip_input(struct pbuf *p,struct netif *inp){struct ?? ?ip_hdr *iphdr;?? ?// 指向IP包頭的指針struct ?? ?netif *netif;?? ?// 指向netif硬件網(wǎng)絡(luò)接口設(shè)備描述符的指針u16_t?? ?iphdr_hlen;?? ??? ?// IP包頭的長(zhǎng)度,通常是固定20字節(jié)u16_t?? ?iphdr_len;?? ??? ?// 整個(gè)IP包長(zhǎng),包含IP包頭、上層協(xié)議頭、數(shù)據(jù)// 取出 IP數(shù)據(jù)包頭iphdr = (struct ip_hdr *)p->payload;// 檢查IP包頭中的版本號(hào)字段,IPv4 - 4,IPv6 - 6if(IPH_V(iphdr) != 4){pbuf_free(p);return ERR_OK;?? ?}// 提取IP包頭中的頭長(zhǎng)度字段,通常固定值20字節(jié)iphdr_hlen = IPH_HL(iphdr);iphdr_hlen *= 4;// 提取IP包頭中的IP包總長(zhǎng)度字段,確保小于遞交上來的pbuf包中的總長(zhǎng)度iphdr_len = ntohs(IPH_LEN(iphdr));if(iphdr_len > p->len || iphdr_len > p->tot_len){pbuf_free(p);return ERR_OK;?? ?}// 校驗(yàn)IP數(shù)據(jù)包頭if (inet_chksum(iphdr, iphdr_hlen) != 0){pbuf_free(p);return ERR_OK;?? ?}// 對(duì)IP數(shù)據(jù)報(bào)進(jìn)行截?cái)?#xff0c;得到完整無(wú)冗余IP數(shù)據(jù)包pbuf_realloc(p, iphdr_len);// 遍歷netif_list鏈表(系統(tǒng)存在2個(gè)網(wǎng)卡設(shè)備,意味著有2個(gè)netif分別用于描述它們,也意味著本機(jī)有2個(gè)IP地址,所以此時(shí)就需要遍歷),檢測(cè)IP數(shù)據(jù)包中的目的IP是否與本機(jī)相符,不符則丟棄或轉(zhuǎn)發(fā)ip_addr_copy(current_iphdr_dest, iphdr->dest);ip_addr_copy(current_iphdr_src, iphdr->src);int first = 1;netif = inp;do{// 通過netif->flag標(biāo)志位判斷該網(wǎng)卡設(shè)備是否配置且使能,同時(shí)判斷本機(jī)IP是否有效if ((netif_is_up(netif)) && (!ip_addr_isany(&(netif->ip_addr)))){// 如果目的IP地址與本機(jī)IP地址匹配或者目的IP地址是廣播類型,意味著成功匹配,退出遍歷if(ip_addr_cmp(&current_iphdr_dest, &(netif->ip_addr)) || ip_addr_isbroadcast(&current_iphdr_dest, netif))?? ?{break;?? ?}}if (first){first = 0;netif = netif_list;}else{netif = netif->next;}if (netif == inp){netif = netif->next;}}while(netif != NULL);//? 如果該數(shù)據(jù)包中的源IP地址是廣播IP,則直接丟棄if ((ip_addr_isbroadcast(&current_iphdr_src, inp)) || (ip_addr_ismulticast(&current_iphdr_src))){pbuf_free(p);return ERR_OK;}// 遍歷完成以后,如果依舊沒有找到匹配的netif結(jié)構(gòu)體,說明該數(shù)據(jù)包不是給本機(jī)的,轉(zhuǎn)發(fā)或丟棄(這里直接丟棄)if (netif == NULL){pbuf_free(p);return ERR_OK;}// 判斷該IP包是否是分片數(shù)據(jù)包// 如果是分片數(shù)據(jù)包,則需要將該分片包暫存,等接收完所有分片包后,統(tǒng)一將整個(gè)數(shù)據(jù)包提交給上層if ((IPH_OFFSET(iphdr) & PP_HTONS(IP_OFFMASK | IP_MF)) != 0){// 在這里重組接收到的分片包,如果還沒接收完整,p=NULLp = ip_reass(p);// 如果分片包還沒接收完整,本函數(shù)結(jié)束if (p == NULL){return ERR_OK;}// 如果分片包接收完整,這時(shí)的p已經(jīng)是一個(gè)完整的數(shù)據(jù)包結(jié)構(gòu)體了// 再?gòu)膒中獲取完整的IP包iphdr = (struct ip_hdr *)p->payload;?? ??? ??? ?}// 能到達(dá)這一步的數(shù)據(jù)包必然是未分片的或經(jīng)過分片重組完整后的數(shù)據(jù)包c(diǎn)urrent_netif = inp;current_header = iphdr;if (raw_input(p, inp) == 0){// 根據(jù)IP數(shù)據(jù)包頭中的協(xié)議字段判斷該數(shù)據(jù)包應(yīng)該被遞交給上層哪個(gè)協(xié)議switch (IPH_PROTO(iphdr)){case IP_PROTO_UDP:?? ?// UDP協(xié)議udp_input(p, inp);?? ?// 從這里進(jìn)入傳輸層,解析見下文break;?? ?case IP_PROTO_TCP:?? ?// TCP協(xié)議tcp_input(p, inp);?? ?// 從這里進(jìn)入傳輸層,解析見下文break;case IP_PROTO_ICMP:?? ?// ICMP協(xié)議icmp_input(p, inp);break;case IP_PROTO_IGMP:?? ?// IGMP協(xié)議igmp_input(p, inp, &current_iphdr_dest);break;default:?? ??? ??? ?// 如果都不是// 如果不是廣播數(shù)據(jù)包,返回一個(gè)協(xié)議不可達(dá)ICMP數(shù)據(jù)包給源主機(jī)if (!ip_addr_isbroadcast(&current_iphdr_dest, inp) && !ip_addr_ismulticast(&current_iphdr_dest)){p->payload = iphdr;icmp_dest_unreach(p, ICMP_DUR_PROTO);}?? ?pbuf_free(p);?? ??? ?}?? ?}current_netif = NULL;current_header = NULL;ip_addr_set_any(&current_iphdr_src);ip_addr_set_any(&current_iphdr_dest);}IP層的補(bǔ)充協(xié)議:ICMP、IGMP這時(shí)候主機(jī)A學(xué)到了主機(jī)B的MAC地址,就把這個(gè)MAC封裝到ICMP協(xié)議中向主機(jī)B發(fā)送,報(bào)文格式如下:包頭14字節(jié)?? ??? ??? ??? ??? ??? ??? ??? ??? ??? ?:因?yàn)镮CMP協(xié)議包屬于網(wǎng)絡(luò)層協(xié)議,所以幀類型是0x0800+?? ?ICMP協(xié)議頭(主要是二級(jí)協(xié)議類型、源IP、目的IP)?? ?:二級(jí)協(xié)議類型ICMP對(duì)應(yīng)值0x01+?? ?ICMP協(xié)議主體(主要是一個(gè)類別)?? ??? ??? ??? ??? ?:類別取值0x00 - 這是一條回應(yīng)信息?? ?0x03 - 目的不可達(dá)?? ?0x08 - 請(qǐng)求回應(yīng)信息---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

?

總結(jié)

以上是生活随笔為你收集整理的lwip之数据收发流程_1的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 精品福利在线 | 国产天堂久久 | av在线免费播放网址 | 亚洲影视一区二区三区 | 亚洲综合激情另类小说区 | 国产精品免费观看视频 | 69xxx免费视频 | 九九热视频这里只有精品 | 色倩网站| 国产视频欧美 | 欧美香蕉视频 | 天堂网2018 | 午夜影院欧美 | 人妻熟人中文字幕一区二区 | 精品国产成人av在线免 | 欧美一级片在线观看 | 免费网站看av | 色姑娘综合 | 在线免费看黄视频 | 亚洲人视频在线 | 国产三级黄色 | 91免费短视频 | 久久久精品久久久 | 狠狠操女人 | 成人毛片18女人 | 亚洲色欧美另类 | 本道综合精品 | 色播日韩 | av在线播放不卡 | 91成人在线免费 | 成人欧美一区二区三区黑人免费 | 国产激情久久 | 网站一级片 | 天天操狠狠操夜夜操 | 性色一区 | 五月天视频 | 噜啪啪| 亚洲综合图片网 | 亚洲美女视频在线观看 | 经典三级久久 | 香蕉在线影院 | 国产+日韩+欧美 | 久久国产精品一区二区三区 | 亚洲欧美日韩综合在线 | 无码国产69精品久久久久网站 | 亚洲av无码乱码在线观看富二代 | 日本a在线 | 一级香蕉视频在线观看 | 欧美精品性视频 | a猛片 | 五月婷婷开心 | 蘑菇视频黄色 | 国产男女猛烈无遮挡免费视频 | 激情小说av | 歪歪视频在线观看 | 五号特工组之偷天换月 | 国精产品一区一区三区视频 | 大香蕉视频一区二区 | 黄色小说网站在线观看 | 国产精品久久久久毛片软件 | 黄色片子免费看 | 亚洲欧美自拍一区 | 香港三日本三级少妇66 | 欧美成人看片黄a免费看 | 人人综合网 | 91av视频播放| 国产麻豆电影在线观看 | 久久深夜视频 | 免费黄色av| 国产麻豆乱码精品一区二区三区 | 国产福利在线播放 | 久久国产美女 | 丝袜av网站 | 乱日视频 | av在线小说| 中文字幕一区二区人妻痴汉电车 | 中文字幕视频一区 | 午夜久久乐 | 色综合天天色 | 九九热精品免费视频 | 嫩草网站在线观看 | 欧美性猛交xx | 日韩午夜视频在线观看 | 欧美精品一区二区三区视频 | 国产精品不卡一区二区三区 | 亚洲国产精品久久人人爱 | 好吊色免费视频 | 免费的黄色网址 | 蜜桃精品视频在线 | 蜜桃av成人永久免费 | 欧美午夜在线视频 | 我的好妈妈在线观看 | 爱爱网站免费 | 红桃av | 日韩视频一区二区三区在线播放免费观看 | 欧美激情第1页 | 午夜精品一区二区三区免费视频 | 在线se| 欧美一级片网址 |