esp32s3中使用双通道通信解决TCP粘包问题

在使用esp32 idf例程中的tcp_server和tcp_client通信测试时发现,

在tcp_server端,接收到一帧数据之后必须马上回复至少一个字节,才能保证每帧数据不粘包,

如果不回复操作,300ms以内的通信时延会导致tcp严重粘包,后续解析这些数据费时费力,

可能跟lwip的回环读写机制有关,这严重打乱了双向通信逻辑。

换一种方式,使用udp广播来作为数据传输通道,使用tcp连接来做状态检测,这样就可以

避免粘包问题。

udp广播服务如下


/**
 * udp服务器,高速通信,控制器控制命令传输通道(不需要应答的)
 * */
static void udp_server_task(void *pvParameters)
{
    unsigned char rx_buffer[128];
    char addr_str[128];
    int addr_family = (int)pvParameters;//ipv4 or ipv6
    int ip_protocol = 0;
    struct sockaddr_in6 dest_addr;

    while (1) {

        if (addr_family == AF_INET) {
            struct sockaddr_in *dest_addr_ip4 = (struct sockaddr_in *)&dest_addr;
            /***
             * 接收广播地址:
             * 192.168.100.1
             * 192.168.100.255
             * 255.255.255.255
             */
            dest_addr_ip4->sin_addr.s_addr = htonl(INADDR_ANY);
            dest_addr_ip4->sin_family = AF_INET;
            dest_addr_ip4->sin_port = htons(UDP_SERVER_PORT);
            ip_protocol = IPPROTO_IP;
        } else if (addr_family == AF_INET6) {
            bzero(&dest_addr.sin6_addr.un, sizeof(dest_addr.sin6_addr.un));
            dest_addr.sin6_family = AF_INET6;
            dest_addr.sin6_port = htons(UDP_SERVER_PORT);
            ip_protocol = IPPROTO_IPV6;
        }

        global_udpsock_handle = socket(addr_family, SOCK_DGRAM, ip_protocol);
        if (global_udpsock_handle < 0) {
            ESP_LOGE(TAG, "Unable to create socket: errno %d", errno);

            /**因为正在创建的时候网络可能还没有完全连接上,不能退出*/
            vTaskDelay(100 / portTICK_PERIOD_MS);//100ms
            continue;
        }
        ESP_LOGI(TAG, "UDP Socket created");

#if defined(CONFIG_LWIP_NETBUF_RECVINFO) && !defined(CONFIG_EXAMPLE_IPV6)
        int enable = 1;
        lwip_setsockopt(sock, IPPROTO_IP, IP_PKTINFO, &enable, sizeof(enable));
#endif

#if defined(CONFIG_EXAMPLE_IPV4) && defined(CONFIG_EXAMPLE_IPV6)
        if (addr_family == AF_INET6) {
            // Note that by default IPV6 binds to both protocols, it is must be disabled
            // if both protocols used at the same time (used in CI)
            int opt = 1;
           
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值