OpenEdv-开源电子网

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

LWIP客户端发送数据,总是丢失或一次发好几个

[复制链接]

52

主题

334

帖子

0

精华

高级会员

Rank: 4

积分
560
金钱
560
注册时间
2016-4-12
在线时间
230 小时
发表于 2017-8-4 15:57:44 | 显示全部楼层 |阅读模式
1金钱
如题,我用的LWIP官网例程改的,参考原子例程改了tcp_client_poll函数,如下:static err_t tcp_echoclient_connected(void *arg, struct tcp_pcb *tpcb, err_t err)
{
  struct echoclient *es = NULL;

  es = (struct echoclient *)mem_malloc(sizeof(struct echoclient));

  if (es != NULL)
  {
    es->state = ES_CONNECTED;
    es->pcb = tpcb;
                es->p_tx = NULL;
                tcp_arg(tpcb, es);
                //tcp_sent(tpcb, tcp_echoclient_sent);
                tcp_poll(tpcb, tcp_echoclient_poll, 1);
                err = ERR_OK;
}

static err_t tcp_echoclient_poll(void *arg, struct tcp_pcb *tpcb)
{
  err_t ret_err;
  struct echoclient *es;

  es = (struct echoclient*)arg;
        test6_init();
  if (es != NULL)
  {
                es->p_tx = pbuf_alloc(PBUF_TRANSPORT, strlen((char*)test) , PBUF_POOL);         
    pbuf_take(es->p_tx, (char *)test, strlen((char *)test));
                led_onf();
                tcp_echoclient_send_test(tpcb, es);
                //tcp_echoclient_send(tpcb, es);
                if (es->p_tx)
                        pbuf_free(es->p_tx);
                if(es->state == ES_CLOSING) tcp_echoclient_connection_close(tpcb, es);
    ret_err = ERR_OK;
  }
  else
  {
    tcp_abort(tpcb);
    ret_err = ERR_ABRT;
  }
  return ret_err;
}

static void tcp_echoclient_send_test(struct tcp_pcb *tpcb, struct echoclient * es)
{
  struct pbuf *ptr;
  err_t wr_err = ERR_OK;
       
                while ((wr_err == ERR_OK) && ( es->p_tx != NULL) && (es->p_tx->len <= tcp_sndbuf(tpcb)))   
  {
                ptr = es->p_tx;
                wr_err = tcp_write(tpcb, ptr->payload, ptr->len, 0);       

                if (wr_err == ERR_OK)
                {
                        es->p_tx = ptr->next;  
                        if(es->p_tx != NULL)
                        {
                                pbuf_ref(es->p_tx);
                        }
                        pbuf_free(ptr);
                }
                else if(wr_err == ERR_MEM)
                {
                 es->p_tx = ptr;
                }       
                tcp_output(tpcb);         
                }
}

其实和原子例程一模一样的,我每次回调cp_echoclient_poll的时候,重新复制es->p_tx,然后发送,可是会出现下图所示,要么接受不到,要么一下发好几个,接触LWIP已经两个周了,大概了解了下,有好多不懂的地方,求大神不吝赐教!

2222222222.jpg
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

52

主题

334

帖子

0

精华

高级会员

Rank: 4

积分
560
金钱
560
注册时间
2016-4-12
在线时间
230 小时
 楼主| 发表于 2017-8-4 16:01:36 | 显示全部楼层
[mw_shl_code=applescript,true]static err_t tcp_echoclient_connected(void *arg, struct tcp_pcb *tpcb, err_t err)
{
  struct echoclient *es = NULL;

  es = (struct echoclient *)mem_malloc(sizeof(struct echoclient));
  
  if (es != NULL)
  {
    es->state = ES_CONNECTED;
    es->pcb = tpcb;
                es->p_tx = NULL;
                tcp_arg(tpcb, es);
                //tcp_sent(tpcb, tcp_echoclient_sent);
                tcp_poll(tpcb, tcp_echoclient_poll, 1);
                err = ERR_OK;
}
}
static void tcp_echoclient_send_test(struct tcp_pcb *tpcb, struct echoclient * es)
{
  struct pbuf *ptr;
  err_t wr_err = ERR_OK;
       
                while ((wr_err == ERR_OK) && ( es->p_tx != NULL) && (es->p_tx->len <= tcp_sndbuf(tpcb)))   
  {
                ptr = es->p_tx;
                wr_err = tcp_write(tpcb, ptr->payload, ptr->len, 0);       

                if (wr_err == ERR_OK)
                {
                        es->p_tx = ptr->next;  
                        if(es->p_tx != NULL)
                        {
                                pbuf_ref(es->p_tx);
                        }
                        pbuf_free(ptr);
                }
                else if(wr_err == ERR_MEM)
                {
                 es->p_tx = ptr;
                }       
                tcp_output(tpcb);         
                }
}

static err_t tcp_echoclient_poll(void *arg, struct tcp_pcb *tpcb)
{
  err_t ret_err;
  struct echoclient *es;

  es = (struct echoclient*)arg;
        test6_init();
  if (es != NULL)
  {
                es->p_tx = pbuf_alloc(PBUF_TRANSPORT, strlen((char*)test) , PBUF_POOL);         
    pbuf_take(es->p_tx, (char *)test, strlen((char *)test));
                led_onf();
                tcp_echoclient_send_test(tpcb, es);
                //tcp_echoclient_send(tpcb, es);
                if (es->p_tx)
                        pbuf_free(es->p_tx);
                if(es->state == ES_CLOSING) tcp_echoclient_connection_close(tpcb, es);
    ret_err = ERR_OK;
  }
  else
  {
    tcp_abort(tpcb);
    ret_err = ERR_ABRT;
  }
  return ret_err;
}[/mw_shl_code]
回复

使用道具 举报

52

主题

334

帖子

0

精华

高级会员

Rank: 4

积分
560
金钱
560
注册时间
2016-4-12
在线时间
230 小时
 楼主| 发表于 2017-8-4 16:02:04 | 显示全部楼层
为了方便看代码,我重新贴了下,刚找到怎么黏代码
回复

使用道具 举报

52

主题

334

帖子

0

精华

高级会员

Rank: 4

积分
560
金钱
560
注册时间
2016-4-12
在线时间
230 小时
 楼主| 发表于 2017-8-4 16:03:43 | 显示全部楼层
自己顶自己吧,tcp_echoclient_connected函数里,还有一段else代码,关掉连接的,我没粘好,大神们可以忽略
回复

使用道具 举报

119

主题

439

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1185
金钱
1185
注册时间
2015-9-18
在线时间
422 小时
发表于 2017-8-4 16:21:22 | 显示全部楼层
当时玩lwip的时候,记得tcp协议有这样一个设置,我描述下:

可以设置缓冲区接收数据到达指定上限才回送数据;也可以设置只要接收到数据(哪怕只接收到一个字节)就回送数据。

你查下,看有无这种可能。
电子爱好者
回复

使用道具 举报

1

主题

10

帖子

0

精华

新手上路

积分
33
金钱
33
注册时间
2017-10-17
在线时间
3 小时
发表于 2018-1-2 11:11:44 | 显示全部楼层
liuchang 发表于 2017-8-4 16:21
当时玩lwip的时候,记得tcp协议有这样一个设置,我描述下:

可以设置缓冲区接收数据到达指定上限才回送 ...

你好,这个设置在哪可以找到
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2024-11-24 21:34

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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