OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 8374|回复: 11

探索者lwip例程中tcp_server_senddata函数的一点疑问

[复制链接]

1

主题

8

帖子

0

精华

新手上路

积分
48
金钱
48
注册时间
2015-11-13
在线时间
1 小时
发表于 2015-11-13 16:48:09 | 显示全部楼层 |阅读模式
5金钱
近日在学习lwip,在网上看到了原子哥的lwip开发手册,非常有帮助,于是按照手册移植了一下,已经可以ping通。
但在继续移植服务器端的时候对tcp_server_senddata函数产生了一些疑问。

在开发板作客户端的时候tcp_client_senddata函数是这样的
[mw_shl_code=c,true]//此函数用来发送数据 void tcp_client_senddata(struct tcp_pcb *tpcb, struct tcp_client_struct * es) { struct pbuf *ptr; err_t wr_err=ERR_OK; while((wr_err==ERR_OK)&&es->p&&(es->p->len<=tcp_sndbuf(tpcb))) { ptr=es->p; wr_err=tcp_write(tpcb,ptr->payload,ptr->len,1); //将要发送的数据加入到发送缓冲队列中 if(wr_err==ERR_OK) { es->p=ptr->next; //指向下一个pbuf if(es->p)pbuf_ref(es->p); //pbuf的ref加一 pbuf_free(ptr); //释放ptr }else if(wr_err==ERR_MEM)es->p=ptr; tcp_output(tpcb); //将发送缓冲队列中的数据立即发送出去 } } [/mw_shl_code]
而在tcp_server_senddata
[mw_shl_code=c,true]//此函数用来发送数据 void tcp_server_senddata(struct tcp_pcb *tpcb, struct tcp_server_struct *es) { struct pbuf *ptr; u16 plen; err_t wr_err=ERR_OK; while((wr_err==ERR_OK)&&es->p&&(es->p->len<=tcp_sndbuf(tpcb))) { ptr=es->p; wr_err=tcp_write(tpcb,ptr->payload,ptr->len,1); if(wr_err==ERR_OK) { plen=ptr->len; es->p=ptr->next; //指向下一个pbuf if(es->p)pbuf_ref(es->p); //pbuf的ref加一 pbuf_free(ptr); tcp_recved(tpcb,plen); //更新tcp窗口大小 }else if(wr_err==ERR_MEM)es->p=ptr; } } [/mw_shl_code]
问题有:
1.服务器发送倒数第二句tcp_recved调用的作用是什么?
2.为什么不掉用tcp_output将数据发送出去?

对lwip这块的初学,请大家指教。

最佳答案

查看完整内容[请看2#楼]

1、tcp_recve()是用来更新接收窗口大小的,开发板作为服务器的时候要调用,做客户端的时候不需要调用。如果不调用tcp_receve()更新接收窗口的话,会使得服务器上的数据始终不能满足发送的窗口条件,从而导致该方向上的数据发送停止。 2、tcp_output()是将某个连接的TCP控制块中的unsend队列中的数据发送出去,这个函数用户不需要自己调用,因为LWIP在判断要发送的数据达到一定程度的时候会自动调用tcp_output()的,用户应用程序可 ...
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

88

主题

7377

帖子

5

精华

资深版主

Rank: 8Rank: 8

积分
14980
金钱
14980
注册时间
2013-11-13
在线时间
1823 小时
发表于 2015-11-13 16:48:10 | 显示全部楼层
1、tcp_recve()是用来更新接收窗口大小的,开发板作为服务器的时候要调用,做客户端的时候不需要调用。如果不调用tcp_receve()更新接收窗口的话,会使得服务器上的数据始终不能满足发送的窗口条件,从而导致该方向上的数据发送停止。
2、tcp_output()是将某个连接的TCP控制块中的unsend队列中的数据发送出去,这个函数用户不需要自己调用,因为LWIP在判断要发送的数据达到一定程度的时候会自动调用tcp_output()的,用户应用程序可以不用调用。
开往春天的手扶拖拉机
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165426
金钱
165426
注册时间
2010-12-1
在线时间
2113 小时
发表于 2015-11-13 20:16:17 | 显示全部楼层
1,有注释。
2,你可以测试下。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

1

主题

8

帖子

0

精华

新手上路

积分
48
金钱
48
注册时间
2015-11-13
在线时间
1 小时
 楼主| 发表于 2015-11-14 18:46:08 | 显示全部楼层
回复【2楼】正点原子:
---------------------------------
谢谢原子哥的回复,不过问问题的原因就是注释没看懂,更新tcp窗口大小,是发送窗口大小吗,那为什么用tcp_recvd这个是不是更新接收窗口啊。另外,客户端的发送函数里为什么没有这个调用。
tcp_output那个不马上调用是不是为了等到poll的时候才发出去。

还请原子哥不吝赐教,谢谢。
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165426
金钱
165426
注册时间
2010-12-1
在线时间
2113 小时
发表于 2015-11-15 23:59:20 | 显示全部楼层
回复【3楼】murphy76:
---------------------------------
我让我同事回复你。
lwip我也不太熟。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

1

主题

8

帖子

0

精华

新手上路

积分
48
金钱
48
注册时间
2015-11-13
在线时间
1 小时
 楼主| 发表于 2015-11-16 11:42:07 | 显示全部楼层
回复【4楼】正点原子:
---------------------------------
谢谢原子哥,这么晚还在回复帖子,注意休息哦。
回复

使用道具 举报

1

主题

8

帖子

0

精华

新手上路

积分
48
金钱
48
注册时间
2015-11-13
在线时间
1 小时
 楼主| 发表于 2015-11-17 09:00:24 | 显示全部楼层
期待高人的回复
回复

使用道具 举报

1

主题

8

帖子

0

精华

新手上路

积分
48
金钱
48
注册时间
2015-11-13
在线时间
1 小时
 楼主| 发表于 2015-11-18 10:50:06 | 显示全部楼层
回复【7楼】zuozhongkai:
---------------------------------
谢谢版主的回复
1.tcp_recved()是用来更新接收窗口大小的没错,我不明白的是为什么在Demo程序的发送函数中会被调用。
2.如果我发送的数据量比较大,等不及LWIP自动调用(可能是在tcp_fasttmr中),我是否可以手动调用tcp_output()强制发送出去。
回复

使用道具 举报

88

主题

7377

帖子

5

精华

资深版主

Rank: 8Rank: 8

积分
14980
金钱
14980
注册时间
2013-11-13
在线时间
1823 小时
发表于 2015-11-18 12:27:14 | 显示全部楼层
1、因为你要将你的接收窗口大小值发送给对方,对方知道了你的窗口大小下次就会按照这个大小给你发送数据,所以肯定是在发送函数中的
2、理论上可以,但是最好不要直接这样,让LWIP自己来决定
开往春天的手扶拖拉机
回复

使用道具 举报

1

主题

8

帖子

0

精华

新手上路

积分
48
金钱
48
注册时间
2015-11-13
在线时间
1 小时
 楼主| 发表于 2015-11-18 14:44:51 | 显示全部楼层
回复【9楼】zuozhongkai:
---------------------------------
1.还是不太明白,将我的接收窗口大小值通知对方,是不是应该在我的接收函数中调用的,我向对方发送了数据,会对我的接收窗口造成影响吗,有点晕了。
2.我大概每5ms要传送1K数据,等LWIP发送处理可能会丢数,我先试试主动调用,看看有没有问题。
回复

使用道具 举报

88

主题

7377

帖子

5

精华

资深版主

Rank: 8Rank: 8

积分
14980
金钱
14980
注册时间
2013-11-13
在线时间
1823 小时
发表于 2015-11-18 14:50:39 | 显示全部楼层
还是建议你去看TCP/IP协议去吧,配套这看LWIP的源码
开往春天的手扶拖拉机
回复

使用道具 举报

2

主题

12

帖子

0

精华

初级会员

Rank: 2

积分
99
金钱
99
注册时间
2016-12-6
在线时间
16 小时
发表于 2016-12-6 11:18:01 | 显示全部楼层
原子哥为什么用tcp_output(pcb)后并没有清理tcp_write(pcb,data,len,1)复制保存在RAM的数据,write的数据是保存在RAM中的这有关MEM_SIZE值的设置,是不是需要循环中断一次才能清理RAM的数据,MEM_SIZE 要设置很大才能发送大量数据,应用的开发板不可能说是无限大的内存
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-4-9 01:40

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表