硬汉嵌入式论坛

 找回密码
 立即注册
查看: 1198|回复: 14
收起左侧

[ThreadX全家桶] H7 NETX TCP客户端连接上服务器以后,发几条数据就断开了,请教大佬,这是什么原因?

[复制链接]

4

主题

19

回帖

31

积分

新手上路

积分
31
发表于 2024-5-31 17:39:28 | 显示全部楼层 |阅读模式
H7板卡创建的TCP客户端,直接连接电脑,Ping的时候,几千包都没有问题,但是电脑创建一个服务器以后,连接上以后,没发几包数据就断开了,不发送数据光接收数据也是如此,过一段时间后就自动断开了。返回NX_NOT_CONNECTED


效果

效果
回复

使用道具 举报

0

主题

11

回帖

11

积分

新手上路

积分
11
发表于 2024-5-31 22:45:31 | 显示全部楼层
附上代码:数据接收
回复

使用道具 举报

0

主题

11

回帖

11

积分

新手上路

积分
11
发表于 2024-5-31 22:46:11 | 显示全部楼层
数据接收:
[C] 纯文本查看 复制代码
static VOID nx_app_thread_entry(ULONG thread_input)
{
    /* USER CODE BEGIN Nx_App_Thread_Entry 0 */
    UINT ret = NX_SUCCESS;
    ULONG socket_state;
    NX_PACKET *RxPacket;
    ULONG bytes_read;

    ULONG peer_ip_address;
    ULONG peer_port;

    // 测试时使用端到端(直接连接电脑),初始化需要一定时间,这里延时一段时间再去连接服务器
    tx_thread_sleep(10000);

    /* 创建TCP Socket */
    ret = nx_tcp_socket_create(&NetXDuoEthIpInstance, /* IP实例控制块 */
                               &TCPSocket,            /* TCP控制块 */
                               "TCP Client Socket",   /* TCP Socket名 */
                               NX_IP_NORMAL,          /* IP服务类型 */
                               NX_FRAGMENT_OKAY,      /* 使能IP分段 */
                               NX_IP_TIME_TO_LIVE,    /* 指定一个 8 位的值,用于定义此数据包在被丢弃之前可通过的路由器数目 */
                               1024,                  /* TCP Socket接收队列中允许的最大字节数 */
                               NX_NULL,               /* 用于在接收流中检测到紧急数据时调用的回调函数 */
                               NX_NULL);              /* TCP Socket另一端发出断开连接时调用的回调函数 */
    if (ret)
    {
        log_i("TCP Client socket create failed:0x%x", ret);
        while (1)
        {
            tx_thread_sleep(1000);
        }
    }

    /* 绑定端口 */
    ret = nx_tcp_client_socket_bind(&TCPSocket, NX_APP_DEFAULT_PORT, NX_WAIT_FOREVER);
    if (ret != NX_SUCCESS)
    {
        log_i("TCP Client socket bind port failed:0x%x", ret);
        while (1)
        {
            tx_thread_sleep(1000);
        }
    }

    /* 连接远程服务器 */
    ret = nx_tcp_client_socket_connect(&TCPSocket, TCP_SERVER_ADDRESS, TCP_SERVER_PORT, NX_WAIT_FOREVER);
    if (ret != NX_SUCCESS)
    {
        log_i("TCP Client socket connect server failed:0x%x", ret);
        while (1)
        {
            tx_thread_sleep(1000);
        }
    }

    // tx_thread_resume(&TCP_Send_Thread);
    while (1)
    {
        TX_MEMSET(data_buffer, '\0', sizeof(data_buffer));

        /* 获取socket状态 */
        nx_tcp_socket_info_get(&TCPSocket,    /* TCP Socket控制块 */
                               NULL,          /* 发送的TCP数据包总数目 */
                               NULL,          /* 发送的TCP总字节数 */
                               NULL,          /* 接收TCP数据包总数目 */
                               NULL,          /* 接收的TCP总字节数 */
                               NULL,          /* 重新传输的TCP数据包总数目 */
                               NULL,          /* Socket上TCP排队的TCP数据包总数 */
                               NULL,          /* Socket上有校验和错误的TCP数据包总数 */
                               &socket_state, /* Socket当前状态 */
                               NULL,          /* 仍在排队等待ACK的发送数据包总数 */
                               NULL,          /* 当前发送窗口大小 */
                               NULL);         /* 当前接收窗口大小 */

        /* 如果连接还没有建立,继续接受新连接,成功的话开启接收数据 */
        if (socket_state != NX_TCP_ESTABLISHED)
        {
            log_i("TCP socket is not established!!!");
            /* 绑定端口 */
            ret = nx_tcp_client_socket_bind(&TCPSocket, NX_APP_DEFAULT_PORT, NX_WAIT_FOREVER);

            if (ret != NX_SUCCESS)
            {
                log_i("TCP Client socket rebind port failed:0x%x", ret);
                tx_thread_sleep(100);
            }

            /* 连接远程服务器 */
            ret = nx_tcp_client_socket_connect(&TCPSocket, TCP_SERVER_ADDRESS, TCP_SERVER_PORT, NX_WAIT_FOREVER);

            if (ret != NX_SUCCESS)
            {
                log_i("TCP Client socket reconnect server failed:0x%x", ret);
                tx_thread_sleep(100);
            }
        }

        if ((socket_state == NX_TCP_ESTABLISHED) && (ret == NX_SUCCESS))
        {
            log_i("TCP socket is established");
            /* 接收TCP客户端发的TCP数据包 */
            ret = nx_tcp_socket_receive(&TCPSocket,       /* TCP Socket控制块 */
                                        &RxPacket,        /* 接收到的数据包 */
                                        NX_WAIT_FOREVER); /* 永久等待 */

            if (ret == NX_SUCCESS)
            {

                /* 获取客户端的IP地址和端口 */
                ret = nx_tcp_socket_peer_info_get(&TCPSocket,       /* TCP Socket控制块 */
                                                  &peer_ip_address, /* 远程IP地址 */
                                                  &peer_port);      /* 远程端口号 */
                if (ret != NX_SUCCESS)
                {
                    log_i("TCP Client get ip addr and port failed:0x%x", ret);
                    while (1)
                    {
                        tx_thread_sleep(1000);
                    }
                }

                /* 获取客户端发来的数据 */
                ret = nx_packet_data_retrieve(RxPacket,     /* 接收到的数据包 */
                                              data_buffer,  /* 解析出数据 */
                                              &bytes_read); /* 数据大小 */
                if (ret != NX_SUCCESS)
                {
                    log_i("TCP Client parse rev data failed:0x%x", ret);
                    while (1)
                    {
                        tx_thread_sleep(1000);
                    }
                }

                /* 打印接收到数据 */
                PRINT_DATA(peer_ip_address, (unsigned int)peer_port, data_buffer);

                ret = nx_packet_release(RxPacket);
                if (ret != NX_SUCCESS)
                {
                    log_i("rx packet release failed:0x%x", ret);
                    while (1)
                    {
                        tx_thread_sleep(1000);
                    }
                }
            }
            else
            {
                log_i("TCP Client receive data failed:0x%x", ret);
                /* 释放数据包 */
                nx_packet_release(RxPacket);

                /* 断开连接 */
                nx_tcp_socket_disconnect(&TCPSocket, NX_WAIT_FOREVER);

                /* disconnect the socket */
                nx_tcp_client_socket_unbind(&TCPSocket);
            }
        }
    }
    /* USER CODE END Nx_App_Thread_Entry 0 */
}


数据发送:
[C] 纯文本查看 复制代码
static VOID TCP_Send_Thread_entry(ULONG thread_input)
{
    UINT ret = NX_SUCCESS;
    ULONG socket_state;
    NX_PACKET *TxPacket;

    uint8_t sendbuf[20];
    uint32_t count = 0;
    while (1)
    {
        /* 获取socket状态 */
        nx_tcp_socket_info_get(&TCPSocket,    /* TCP Socket控制块 */
                               NULL,          /* 发送的TCP数据包总数目 */
                               NULL,          /* 发送的TCP总字节数 */
                               NULL,          /* 接收TCP数据包总数目 */
                               NULL,          /* 接收的TCP总字节数 */
                               NULL,          /* 重新传输的TCP数据包总数目 */
                               NULL,          /* Socket上TCP排队的TCP数据包总数 */
                               NULL,          /* Socket上有校验和错误的TCP数据包总数 */
                               &socket_state, /* Socket当前状态 */
                               NULL,          /* 仍在排队等待ACK的发送数据包总数 */
                               NULL,          /* 当前发送窗口大小 */
                               NULL);         /* 当前接收窗口大小 */

        /* 如果连接还没有建立,继续接受新连接,成功的话开启接收数据 */
        if (socket_state != NX_TCP_ESTABLISHED)
        {
            tx_thread_sleep(1000);
        }
        else
        {
            ret = nx_packet_allocate(&NxAppPool, &TxPacket, NX_TCP_PACKET, TX_WAIT_FOREVER);
            if (ret != NX_SUCCESS)
            {
                log_i("allocate tx packet failed:0x%x", ret);
                while (1)
                {
                    tx_thread_sleep(1000);
                }
            }

            sprintf((char *)sendbuf, "sendbuf = %d\r\n", count++);

            /*将要发送的数据附加到TraPacket */
            ret = nx_packet_data_append(TxPacket, (VOID *)sendbuf, strlen((char *)sendbuf), &NxAppPool, TX_WAIT_FOREVER);
            if (ret != NX_SUCCESS)
            {
                log_i("packet append data failed:0x%x", ret);
                nx_packet_release(TxPacket);
                while (1)
                {
                    tx_thread_sleep(1000);
                }
            }

            /* 发送数据,注意发送后,此函数会释放数据包 */
            ret = nx_tcp_socket_send(&TCPSocket, TxPacket, NX_WAIT_FOREVER);
            if (ret != NX_SUCCESS)
            {
                log_i("TCP Client send data failed:0x%x", ret);
                while (1)
                {
                    tx_thread_sleep(1000);
                }
            }
            tx_thread_sleep(1000);
        }
    }
}
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
115892
QQ
发表于 2024-6-1 08:37:10 | 显示全部楼层
这个不正常,是不是没有移植好。百万数据包的连续ping测试是否通过了,如果已经通过,说明移植没问题,可以排查应用。

https://www.armbbs.cn/forum.php? ... %B0%D9%CD%F2%2Bping
回复

使用道具 举报

0

主题

11

回帖

11

积分

新手上路

积分
11
发表于 2024-6-1 09:46:02 | 显示全部楼层
eric2013 发表于 2024-6-1 08:37
这个不正常,是不是没有移植好。百万数据包的连续ping测试是否通过了,如果已经通过,说明移植没问题,可以 ...

使用CubeMX创建的工程,关闭了CACHE,直接ping没有任何问题(两千包),添加了TCP客户端的代码以后,工作就不正常了
回复

使用道具 举报

0

主题

11

回帖

11

积分

新手上路

积分
11
发表于 2024-6-1 13:21:13 | 显示全部楼层
C:\Users\97897\Desktop\PING失败.png
ping 一万包。1024字节,一会儿后就出错了
回复

使用道具 举报

0

主题

11

回帖

11

积分

新手上路

积分
11
发表于 2024-6-1 16:17:08 | 显示全部楼层
laozang001 发表于 2024-6-1 13:21
ping 一万包。1024字节,一会儿后就出错了

ping到一半失败了
PING失败.png
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
115892
QQ
发表于 2024-6-2 01:25:46 | 显示全部楼层

这个还不是极速ping,把这个勾上看看,稳定不

127.png
回复

使用道具 举报

4

主题

19

回帖

31

积分

新手上路

积分
31
 楼主| 发表于 2024-6-5 15:31:51 | 显示全部楼层
ping起来贼稳定,百万包也不出错,如果是单纯的TCP 数据接收也不出错,但是一旦把数据发送的代码加上,就发一两条就死了。
回复

使用道具 举报

4

主题

19

回帖

31

积分

新手上路

积分
31
 楼主| 发表于 2024-6-5 16:31:26 | 显示全部楼层
不接收数据,只是单纯的发送数据的话,发两包就Hardfault了。发生位置在_nx_ip_header_add这个函数
hardfault.png

hardfault位置

hardfault位置
回复

使用道具 举报

4

主题

19

回帖

31

积分

新手上路

积分
31
 楼主| 发表于 2024-6-5 19:41:15 | 显示全部楼层
lyj41801 发表于 2024-6-5 16:31
不接收数据,只是单纯的发送数据的话,发两包就Hardfault了。发生位置在_nx_ip_header_add这个函数

而且还是内存访问不对齐的错误
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
115892
QQ
发表于 2024-6-6 09:18:34 | 显示全部楼层
lyj41801 发表于 2024-6-5 19:41
而且还是内存访问不对齐的错误

这种的,应该是你的应用代码实现有点问题。
回复

使用道具 举报

4

主题

19

回帖

31

积分

新手上路

积分
31
 楼主| 发表于 2024-6-6 10:39:38 | 显示全部楼层
一顿排查,UDP没有问题,
但是TCP的话发送数据,就会出现重发超时,导致协议栈自己把scoket关闭了。1秒1条,前面几条为啥没事呢,后面就超时了
close.png
回复

使用道具 举报

4

主题

19

回帖

31

积分

新手上路

积分
31
 楼主| 发表于 2024-6-6 17:13:06 | 显示全部楼层
问题搞定了,一切的问题都是H7的Cache和MPU导致的,不开Cache和MPU还不行,哪怕注释了网络驱动里面的SCB_开头的函数。不开的话,接收没有问题,发送还是会出错。如果打开Cache和MPU又需要很小心很小心,我真的服了。
同时也感谢论坛大佬。
回复

使用道具 举报

3

主题

71

回帖

80

积分

初级会员

积分
80
发表于 2024-6-7 11:09:42 | 显示全部楼层
lyj41801 发表于 2024-6-6 17:13
问题搞定了,一切的问题都是H7的Cache和MPU导致的,不开Cache和MPU还不行,哪怕注释了网络驱动里面的SCB_开 ...

github上有一个azure-h7仓库, 链接可以参考里面的demo,cache和MPU都开了,
回复

使用道具 举报

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

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2025-5-25 11:46 , Processed in 1.447858 second(s), 28 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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