天线|RF射频
直播中

张易

7年用户 159经验值
私信 关注
[问答]

为什么LWIP客户端发送数据总是丢失或一次发好几个?

如题,我用的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已经两个周了,大概了解了下,有好多不懂的地方,求大神不吝赐教!

回帖(5)

彭菲

2019-9-4 08:15:29
[AppleScript] 纯文本查看 复制代码
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;}
举报

陈茹

2019-9-4 08:26:47
为了方便看代码,我重新贴了下,刚找到怎么黏代码
举报

赵媛

2019-9-4 08:39:46
自己顶自己吧,tcp_echoclient_connected函数里,还有一段else代码,关掉连接的,我没粘好,大神们可以忽略
举报

汤艳

2019-9-4 08:49:13
当时玩lwip的时候,记得tcp协议有这样一个设置,我描述下:
可以设置缓冲区接收数据到达指定上限才回送数据;也可以设置只要接收到数据(哪怕只接收到一个字节)就回送数据。
你查下,看有无这种可能。
举报

更多回帖

发帖
×
20
完善资料,
赚取积分