lwip连续发数据卡死_用lwip发送大量数据时,遇到的问题解答记录求索阁...

lwip连续发数据卡死_⽤lwip发送⼤量数据时,遇到的问题解答
记录求索阁
1、概述:
lwip是轻量型的TCP/IP实现,只需10⼏KB的RAM和40⼏KB的ROM就能够跑起来,适合应⽤于嵌⼊式设备的⽹络通信。有⽜⼈Adam Dunkels发明,提供给⽤户上那种接⼝
RAW TCP/IP、Squential API, BSD API(也就是常说的socket编程),前者编程稍微复杂点,协议和应⽤程序在⼀个进程⾥⾯,但是效率⾼。中者⾸先要操作系统的⽀持,但是⼀旦实现了操作系统模拟层的实现,编程妥妥的。后者是为了符合⼈们使⽤socket编程的习惯⽽模拟的socket实现。所以王者乃RAW TCP/IP。⽹上提供了源码的下载,现在已经更新⾄1.4.x(doc 开发与移植指导⽂档, src 源码 test 测试例⼦),doc⾥⾯罗列了RAW TCP/IP的开发接⼝函数mss
2、demo搭建:
服务器端:
0 open_tap()⾥⾯选择适合的⽹卡
1 开辟新进程 sys_thread_new("http thread",server_init, NULL, 0, 0);
2 设定⽹址和默认路由器 netif_add(&netif, &ip, &mask, &gw, NULL, ethernetif_init, tcpip_input);
3 在server_init⾥⾯ 分别调⽤pcb = tcp_new(); tcp_bind(pcb, IP_ADDR_ANY, 8000);pcb = tcp_listen(pcb);
tcp_accept(pcb, server_accept); tcp_poll(pcb, tcp_poll, 10);// 每5s执⾏⼀次tcp_poll;
4 当有新的连接到来时,即有新的数据接收时, server_accept 就好调⽤。在server_accept⾥⾯注册调⽤函数tcp_recv(pcb,
server_recv);
菅义伟为什么只有一年此后每次新的数据过来时,就会调⽤server_recv函数。
5 在函数 static err_t server_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err)⾥⾯对pbuf进⾏分析,要注意p->next的值。
并且借鉴其他资料知道⽴即要调⽤tcp_recevd;很神秘的告诉你要调⽤否则不好使。后⾯这⾥有重要发现。
6 调⽤pbuf_free函数,来释放pbuf;
联想v460驱动客服端:
0~2步基本相同
3在client_init⾥⾯ 分别调⽤pcb = tcp_new(); ret_val = tcp_connect(pcb, &dest, 8000, client_connected);
4 在client_connected⾥⾯发送连接请求。同时调⽤tcp_accept(pcb, client_recv)来注册数据接收处理回调函数。
5 在static err_t client_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err);对接收到的数据进⾏处理
类似server_recv。
搭建完成之后:发现,在server_recv 函数⾥⾯只能够tcp_write 128个字节的数据。当发送⼤于128个数据时,就会只能够接收128个数据。
了半天发现[2]是由opt.h⾥⾯的参数MSS 128决定的, 另外还要注意⼀个参数即TCP_SND_WND 256。
改变这两个后,发送⽐TCP_SND_WND⼩且⽐MSS⼤的数据时, 客户端可以接受到⼀次等于MSS的数据。
试了各种策略后,客户端只接收⼀次。我们甚⾄怀疑是回调函数注册⼀次只能使⽤⼀次的问题,都⽆效。
后⾯查询各种资料[3], 后⾯发现英⽂资料lwip-user给出了很多启⽰:
包括分析TCP segment(底层⾃⾏封装成不同packet,不带ACK) 和 IP segment(>MTU时,会带ACK)
了解了opt.h中:
MSS (the smaller, the better) 128
西塞罗TCP_SND_BUF 256
MEM_SIZE (1600) HEAP SIZE 如果tcp_write ⽤COPY的⽅式时是需要设置较⼤的值;
TCP_SND_QUEUELEN  4*(TCP_SND_BUF/tcp_mss)(最⼩为除式的两倍);
男生女生金版封面
MEMP_NUM_TCP_SEG: ⾄少跟上⾯⼀样⼤
裸持资源
MEMP_NUM_PBUF(16) --->32
TCP_WND 2048 接收窗⼝,接收多少个数据包的问题。
今天通过wireshark抓包发现,1.15 端发送给了 1.111端后⾯多于MSS的数据报⽂,⽽且发送端⼀直发送MSS长度的报⽂,可以得知应该是接收端的没有应答正确。前⾯提到的tcp_recevd调⽤的是tcp_ack函数。其实就是对接收到的数据进⾏应答但是同时发现有⼀个好⽤的函数 tcp_ack_now(pcb),是直接发送应答,因为后⾯跟了tcp_output(pcb)函数。
并且要了解flags 设置 pcb->flags |= TF_NODELAY | TF_ACK_NOW; len = tcp_sndbuf(pcb);会告知剩余的buf的长度并且多次发送的时候可以设置这个值,从⽽⼿动告知系统还有多少buf可以发送,从⽽实现了多次发送的操作。
改了这两处之后,实验可以发送32000个字节,不错。

本文发布于:2024-09-20 12:39:03,感谢您对本站的认可!

本文链接:https://www.17tex.com/xueshu/717728.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:发送   数据   接收   函数   编程   资料   实现   注册
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2024 Comsenz Inc.Powered by © 易纺专利技术学习网 豫ICP备2022007602号 豫公网安备41160202000603 站长QQ:729038198 关于我们 投诉建议