这两天,师弟在两台电脑上搭建了lwipwin32通信平台,目的是能够不断发送一幅幅图片图像大小为1280*720大小的图片。如果不考虑压缩情况且是256色即1字节,这样大小的一幅图片需要发送大约发送1M字节。具有李逵性格的山东师弟目标是:客服端发送一次请求,服务器端能够通过TCP方式一次发送大约1M的数据;我震惊了, 我说你可知道MTU(1500)的上限,以及内存的考虑。当然让每次发送一次数据量尽可能大,这种想法是好的;看着他每天哀声叹气,临近毕业的我深表同情,另外我对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的开发接口函数。

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;

客服端:

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个字节,不错。

参考文档:

[1] http://lwip.wikia.com/wiki/Category:LwIP_Application_Developers_Manual

[2] https://groups.google.com/forum/#!topic/osdeve_mirror_tcpip_lwip/4GAbtXFwlvk

[3] 百度:关于LWIP协议栈连续多次tcp_write后失败的解决过程

[4] lwip design and implementation

lwip连续发数据卡死_用lwip发送大量数据时,遇到的问题解答记录;相关推荐

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

    1.概述: lwip是轻量型的TCP/IP实现,只需10几KB的RAM和40几KB的ROM就能够跑起来,适合应用于嵌入式设备的网络通信.有牛人Adam Dunkels发明,提供给用户上那种接口 RAW ...

  2. lwip连续发数据卡死_LwIP用TCP连接方式在数据量比较大协议栈卡死

    这段时间用STM32移植LwIP做语音传输.但是遇到一个问题困扰许久,在使用TCP方式做一个client去连接server,由于数据量比较大经常在连接一个多小时候就出现断线而 也ping不通.接下来我 ...

  3. keras时间序列数据预测_使用Keras的时间序列数据中的异常检测

    keras时间序列数据预测 Anomaly Detection in time series data provides e-commerce companies, finances the insi ...

  4. 基于plotly数据可视化_如何使用Plotly进行数据可视化

    基于plotly数据可视化 The amount of data in the world is growing every second. From sending a text to clicki ...

  5. 数据多重共线性_多重共线性对您的数据科学项目的影响比您所知道的要多

    数据多重共线性 Multicollinearity is likely far down on a mental list of things to check for, if it is on a ...

  6. 什么事数据科学_如果您想进入数据科学,则必须知道的7件事

    什么事数据科学 No way. No freaking way to enter data science any time soon-That is exactly what I thought a ...

  7. python怎么用大数据分析师_如何七周成为数据分析师18:Python的新手教程

    本文是<怎样 七周成为数据剖析 师>的第十八篇教程,假定 想要了解 写作初衷,能够 先行阅读七周指南.温馨提示:假定 您曾经 熟习 Python,大可不用 再看这篇文章,或只选择 部分 . ...

  8. python大数据免费_用python做大数据

    不学Python迟早会被淘汰?Python真有这么好的前景? 最近几年Python编程语言在国内引起不小的轰动,有超越Java之势,本来在美国这个编程语言就是最火的,应用的非常非常的广泛,而Pytho ...

  9. 数据结构设计_撮合引擎开发:数据结构设计

    价值超5万的撮合引擎:开篇 价值超5万的撮合引擎:MVP版本 交易委托账本 交易委托账本(OrderBook)是整个撮合引擎里最核心也是最复杂的数据结构,每个交易对都需要维护一份交易委托账本,账本里保 ...

最新文章

  1. 高斯混合模型(GaussianMixture Model, GMM)聚类、可视化最优协方差形式、通过TSNE进行结果可视化分析、抽取核心特征因子
  2. 【多线程】join()和detach()的用法
  3. 根据不同的操作系统读取配置文件/java读取属性文件代码
  4. oracle之创建和管理表之练习题
  5. 访问对象的属性和方法
  6. docker build no such file or directory
  7. Unicode 编码解码
  8. ios键盘横屏_平板电脑就只能追剧玩游戏?看这款外设键盘如何让iPad爱上办公...
  9. Appium 屏幕页面滑动(swipe函数实现)
  10. 如何将背景音乐添加到iMovie?
  11. Kibana将语言设置为中文
  12. 计算机VFP试题答案,2010全国计算机vfp二级笔试试题及答案
  13. tex 表格内容换行_LaTeX:表格内换行与各种居中完美解决
  14. 路由器和交换机的转发过程
  15. android设置布局背景为空,android 设置背景为空(透明)
  16. html5图片中加入文字,HTML肿么在图片上添加文字,也就是图片作为背景,代码和图像显示如下...
  17. nginx配置地址端口
  18. MongoDB查询集合中的文档
  19. 《爱上Pandas》系列-你还在用VLookup吗?
  20. 基于JSP网上书店系统的设计与实现

热门文章

  1. ssm项目,测试方法一直转圈,运行不停止
  2. 基于CANoen协议实现DSP系统与上位机CAN的通讯
  3. 涉密计算机能用固态硬盘,电脑硬盘有坏道还能继续使用吗?不要抱侥幸心理,可能后悔莫及...
  4. (转)游戏运营18种方式
  5. 爱奇艺体育获5亿元战略融资 ,IDG资本、汇盈博润领投
  6. 复旦女神陈果:孤独是一个人的狂欢,在你寂寞时请关注这些公众号充实自己
  7. 名帖299 王铎 行书《书法册页李贺诗四首》
  8. Nginx 连接限制和访问控制Nginx 连接限制和访问控制
  9. 数据时代程序员必备技能:数据可视化
  10. SPI Flash芯片W25Q32英文版数据手册解读(三)---------程序编写,电路应用