STM32 LWIP TCP 数据包分包后合并,超过591字节后分会分包问题

最新在使用LWIP + MQTT的应用过程中,出现一个很奇怪的问题,当上位机反送的JSON长度过大时,我的stm32收到的数据就会有问题:

上图中成功接收到失败接收口相关1个字节,用wireshark看数据包长度分别是591和590:

发现可能是我的接收BUFF不够大引起的,程序中有MqttRxBuff大小定义为1024,改成2048还是一样接收失败:

看来问题不是在这个BUFF,

接着看MQtt对应的TCP接收BUFF,在LWIP的opt.h中看到有如下一些定义,从图中看到PBUF_POOL_BUFSIZE大小取决到TCP_MESS大小。当前TCP_MESS大小于536 对应计算出的PBUF_POOL_BUFSIZE为592,刚好与我们之前的591相近,看到就是这个问题我们把

按理把这个参数改大后应该可以解决,但是发现实际发现还是不行!

仿真发现数据从路由器发送到MCU时,就已经分成了两包,最终将TCP的接收函数改写成如下问题解决。

 

/**

  * @brief tcp_receiv callback

  * @param arg: argument to be passed to receive callback

  * @param tpcb: tcp connection control block

  * @param err: receive error code

  * @retval err_t: retuned error

  */

err_t MqttTcp_recv(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err)

{

    struct mqttclinet *es;

    err_t ret_err;

    int i = 0;

 

 

    LWIP_ASSERT("arg != NULL",arg != NULL);

 

    es = (struct mqttclinet *)arg;

 

    /* if we receive an empty tcp frame from server => close connection */

    if (p == NULL)

    {

        /* remote host closed connection */

        es->state = ES_CLOSING;

        if(es->p_tx == NULL)

        {

            /* we're done sending, close connection */

            MqttTcp_connection_close(tpcb, es);

        }

        else

        {

            /* send remaining data*/

            MqttTcp_send(tpcb, es);

        }

        ret_err = ERR_OK;

    }

    /* else : a non empty frame was received from echo server but for some reason err != ERR_OK */

    else if(err != ERR_OK)

    {

        /* free received pbuf*/

        pbuf_free(p);

 

        ret_err = err;

    }

    else if(es->state == ES_CONNECTED)

    {

        /* Acknowledge data reception */

        tcp_recved(tpcb, p->tot_len);

 

#if 0

        // 回显功能

        es->p_tx = p;

        MqttTcp_send(tpcb, es);

 

#else

        // 将要接收的数据放到BUFF里

        if( p->flags == 0 )  //  如果出现了分包的,在这里时行判断

        {

            MqttRxOffset = p->len;

                 memcpy((void *)MqttRxTemp,p->payload,p->len);

        }

        else

        {

            if( MqttRxOffset )

            {

                if( (MqttRxBwp + MqttRxOffset) -  MqttRxBrp < MQTTBUFFSIZE   )

                {

                    for( i=0; i<MqttRxOffset; i++ )

                    {

                        MqttRxBuff[MqttRxBwp] = MqttRxTemp[i];

                        MqttRxBwp = (MqttRxBwp+1)%MQTTBUFFSIZE;

                    }

                }

                       MqttRxOffset = 0;

            }

            if( (MqttRxBwp + p->tot_len) -  MqttRxBrp < MQTTBUFFSIZE   )

            {

                for( i=0; i<p->tot_len; i++)

                {

                    MqttRxBuff[MqttRxBwp] = *((uint8_t *)(p->payload)+i);

                    MqttRxBwp = (MqttRxBwp+1)%MQTTBUFFSIZE;

                }

            }  

        }

        pbuf_free(p);

#endif

        ret_err = ERR_OK;

    }

 

    /* data received when connection already closed */

    else

    {

        /* Acknowledge data reception */

        tcp_recved(tpcb, p->tot_len);

 

        /* free pbuf and do nothing */

        pbuf_free(p);

        ret_err = ERR_OK;

    }

    return ret_err;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值