硬汉嵌入式论坛

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

[ThreadX全家桶] nx_tcp_socket_send无法连续发送问题

[复制链接]

3

主题

9

回帖

18

积分

新手上路

积分
18
发表于 2021-11-5 17:38:11 | 显示全部楼层 |阅读模式
  1. while(1){
  2.     ret = nx_packet_allocate(&AppPool, &data_packet, NX_IPv4_TCP_PACKET, TX_WAIT_FOREVER);

  3.     if (ret != NX_SUCCESS)
  4.     {
  5.             printf("aaaa1\r\n");
  6.       break;
  7.     }

  8.     /* append the message to send into the packet */
  9.     ret = nx_packet_data_append(data_packet, (VOID *)DEFAULT_MESSAGE, sizeof(DEFAULT_MESSAGE), &AppPool, TX_WAIT_FOREVER);

  10.     if (ret != NX_SUCCESS)
  11.     {
  12.             printf("aaaa2\r\n");
  13.       nx_packet_release(data_packet);
  14.       break;
  15.     }

  16.     /* send the packet over the TCP socket */
  17.     ret = nx_tcp_socket_send(&TCPSocket, data_packet, DEFAULT_TIMEOUT);

  18.     if (ret != NX_SUCCESS)
  19.     {
  20. printf("tcp send error:%d\r\n",ret);
  21.       break;
  22.     }

  23.    
  24.    }
复制代码
然后发现报该错误:tcp send error:56我在threadX netxduo的api 文档上看到

下载.png

然后我在发送函数下面加了个延时,tx_thread_sleep(10);就不会报错
看来跟数据包释放有关系,大家有实现不加延时,可以连续发的方法么?

我看了一下api文档,似乎没有一个api可以去判断该数据包是否已经被释放。。。。。



回复

使用道具 举报

3

主题

9

回帖

18

积分

新手上路

积分
18
 楼主| 发表于 2021-11-5 17:39:31 | 显示全部楼层

报错 56 ==0x38,但是我能确保网络是一直连接的
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
115834
QQ
发表于 2021-11-6 09:43:02 | 显示全部楼层
jipolun 发表于 2021-11-5 17:39
报错 56 ==0x38,但是我能确保网络是一直连接的

貌似是你的姿势不太对,发送玩要释放数据包
  1. /*
  2. *********************************************************************************************************
  3. *        函 数 名: NetXTest
  4. *        功能说明: TCPnet应用
  5. *        形    参: 无
  6. *        返 回 值: 无
  7. *********************************************************************************************************
  8. */   
  9. void NetXTest(void)
  10. {
  11.     UINT status;
  12.     UINT ret;
  13.     ULONG socket_state;
  14.     UINT old_priority;

  15.     ULONG source_ip_address;
  16.     NX_PACKET *data_packet;

  17.     UINT source_port;
  18.     ULONG bytes_read;

  19.     /* 创建信号量,用于通知TCP服务器监听到新连接 */
  20.     tx_semaphore_create(&Semaphore, "App Semaphore", 0);
  21.    

  22.     /* 初始化NetX */
  23.     nx_system_initialize();

  24.     /* 创建内存池 */
  25.     status =  nx_packet_pool_create(&pool_0,
  26.                                      "NetX Main Packet Pool",
  27.                                      1536,  (ULONG*)(((int)packet_pool_area + 15) & ~15) ,
  28.                                      NX_PACKET_POOL_SIZE);

  29.     /* 检测创建是否失败 */
  30.     if (status) error_counter++;

  31.     /* 例化IP */
  32.     status = nx_ip_create(&ip_0,
  33.                             "NetX IP Instance 0",
  34.                             IP_ADDRESS(IP_ADDR0, IP_ADDR1, IP_ADDR2, IP_ADDR3),
  35.                             0xFFFFFF00UL,
  36.                             &pool_0, nx_driver_stm32f4xx,
  37.                             (UCHAR*)AppTaskNetXStk,
  38.                             sizeof(AppTaskNetXStk),
  39.                             APP_CFG_TASK_NETX_PRIO);
  40.                            
  41.             
  42.     /* 检测创建是否失败 */
  43.     if (status) error_counter++;

  44.     /* 使能ARP,并提供ARP缓存 */
  45.     status =  nx_arp_enable(&ip_0, (void *)arp_space_area, sizeof(arp_space_area));

  46.     /* 使能fragment */   
  47.     status = nx_ip_fragment_enable(&ip_0);

  48.     /* 检测使能成功 */
  49.     if (status) error_counter++;

  50.     /* 使能TCP */
  51.     status =  nx_tcp_enable(&ip_0);

  52.     /* 检测使能成功 */
  53.     if (status) error_counter++;

  54.     /* 使能UDP  */
  55.     status =  nx_udp_enable(&ip_0);

  56.     /* 检测使能成功 */
  57.     if (status) error_counter++;

  58.     /* 使能ICMP */
  59.     status =  nx_icmp_enable(&ip_0);

  60.     /* 检测使能成功 */
  61.     if (status) error_counter++;   
  62.    
  63.     /* NETX初始化完毕后,重新设置优先级 */
  64.     tx_thread_priority_change(netx_thread_ptr, APP_CFG_TASK_NETX_PRIO1, &old_priority);
  65.     tx_thread_priority_change(&AppTaskNetXProTCB, APP_CFG_TASK_NetXPro_PRIO1, &old_priority);
  66.    
  67.     /////////////////////////////////////////////////////////////////////////////
  68.     /* 创建TCP Socket */
  69.     ret = nx_tcp_socket_create(&ip_0,
  70.                                &TCPSocket,
  71.                                "TCP Server Socket",
  72.                                NX_IP_NORMAL,
  73.                                NX_FRAGMENT_OKAY,
  74.                                NX_IP_TIME_TO_LIVE,
  75.                                4320,
  76.                                NX_NULL,
  77.                                NX_NULL);
  78.     if (ret)
  79.     {
  80.                 Error_Handler(__FILE__, __LINE__);   
  81.     }

  82.     /*
  83.     * 监听新的链接。
  84.     * 创建回调TCP_listen_callback表示监听到新连接。
  85.     */
  86.     ret = nx_tcp_server_socket_listen(&ip_0, DEFAULT_PORT, &TCPSocket, MAX_TCP_CLIENTS, tcp_listen_callback);

  87.     if (ret)
  88.     {
  89.         Error_Handler(__FILE__, __LINE__);
  90.     }

  91.     if(tx_semaphore_get(&Semaphore, TX_WAIT_FOREVER) != TX_SUCCESS)
  92.     {

  93.     }
  94.     else
  95.     {
  96.         /* 启动TCP通信前,接收新连接 */
  97.         ret = nx_tcp_server_socket_accept(&TCPSocket, TX_WAIT_FOREVER);

  98.         if (ret)
  99.         {
  100.             Error_Handler(__FILE__, __LINE__);
  101.         }
  102.     }
  103.    
  104.    
  105.         while(1)
  106.         {
  107.         TX_MEMSET(data_buffer, '\0', sizeof(data_buffer));

  108.         /* 获取socket状态 */
  109.         nx_tcp_socket_info_get(&TCPSocket, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &socket_state, NULL, NULL, NULL);

  110.         /* 如果连接还没有建立,继续接受新连接,成功的话开启接收数据 */
  111.         if(socket_state != NX_TCP_ESTABLISHED)
  112.         {
  113.             ret = nx_tcp_server_socket_accept(&TCPSocket, NX_IP_PERIODIC_RATE);
  114.         }

  115.         if(ret == NX_SUCCESS)
  116.         {
  117.             /* 接收TCP客户端发的TCP数据包 */
  118.             ret = nx_tcp_socket_receive(&TCPSocket, &data_packet, NX_WAIT_FOREVER);

  119.             if (ret == NX_SUCCESS)
  120.             {
  121.                 /* 获取客户端的IP地址和端口 */
  122.                 nx_udp_source_extract(data_packet, &source_ip_address, &source_port);

  123.                 /* 获取客户端发来的数据 */
  124.                 nx_packet_data_retrieve(data_packet, data_buffer, &bytes_read);

  125.                 /* 打印接收到数据 */
  126.                 PRINT_DATA(source_ip_address, source_port, data_buffer);

  127.                 /* 立即将接收到的数据发送回去 */
  128.                 ret =  nx_tcp_socket_send(&TCPSocket, data_packet, NX_IP_PERIODIC_RATE);

  129.                 if (ret == NX_SUCCESS)
  130.                 {

  131.                 }

  132.                 /* 释放数据包 */
  133.                 nx_packet_release(data_packet);
  134.             }
  135.             else
  136.             {
  137.                 /* 断开连接,重新监听 */
  138.                 nx_tcp_socket_disconnect(&TCPSocket, NX_WAIT_FOREVER);
  139.                 nx_tcp_server_socket_unaccept(&TCPSocket);
  140.                 nx_tcp_server_socket_relisten(&ip_0, DEFAULT_PORT, &TCPSocket);
  141.             }
  142.         }
  143.         else
  144.         {
  145.             /* 处于空闲状态 */
  146.             
  147.         }
  148.         }         
  149. }
复制代码


回复

使用道具 举报

3

主题

9

回帖

18

积分

新手上路

积分
18
 楼主| 发表于 2021-11-7 20:00:28 | 显示全部楼层
eric2013 发表于 2021-11-6 09:43
貌似是你的姿势不太对,发送玩要释放数据包

楼主您好,之所以不调用release函数,是因为我看了官网上
貌似这个发送函数会自动释放数据包的


而这边官网上说明 release函数不能重复调用

回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
115834
QQ
发表于 2021-11-8 00:36:03 | 显示全部楼层
jipolun 发表于 2021-11-7 20:00
楼主您好,之所以不调用release函数,是因为我看了官网上
貌似这个发送函数会自动释放数据包的

你看的哪里的说明,方便的话,贴下地址。
回复

使用道具 举报

3

主题

9

回帖

18

积分

新手上路

积分
18
 楼主| 发表于 2021-11-8 10:49:05 | 显示全部楼层
eric2013 发表于 2021-11-8 00:36
你看的哪里的说明,方便的话,贴下地址。

楼主,您好,是这个地址
https://docs.microsoft.com/zh-cn ... #nx_tcp_socket_send
这个函数下面有一句
警告

除非返回了错误,否则应用程序不应在此调用后释放该数据包。这样做会导致不可预知的结果,因为网络驱动程序还会在传输后尝试释放该数据包。
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
115834
QQ
发表于 2021-11-8 16:23:06 | 显示全部楼层
jipolun 发表于 2021-11-8 10:49
楼主,您好,是这个地址
https://docs.microsoft.com/zh-cn/azure/rtos/netx-duo/chapter4#nx_tcp_socke ...

看来要修改,我这个是早期按照他们官方的一个demo设计的,还没有研究他们的API。

近期更新NetXDUO教程得修改下。
回复

使用道具 举报

3

主题

9

回帖

18

积分

新手上路

积分
18
 楼主| 发表于 2021-11-14 22:12:49 | 显示全部楼层
eric2013 发表于 2021-11-8 16:23
看来要修改,我这个是早期按照他们官方的一个demo设计的,还没有研究他们的API。

近期更新NetXDUO教程 ...

所以 我发现
nx_tcp_socket_send()  无法在一个while 连续发送数据
因为测试发现会报(ox38)错误码
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
115834
QQ
发表于 2021-11-15 01:35:42 | 显示全部楼层
jipolun 发表于 2021-11-14 22:12
所以 我发现
nx_tcp_socket_send()  无法在一个while 连续发送数据
因为测试发现会报(ox38)错误码

本周如果如果更新教程的话,我试试,早期我测试没问题的,应该是数据量比较小,无影响。


回复

使用道具 举报

1

主题

75

回帖

78

积分

初级会员

积分
78
发表于 2021-11-15 09:27:54 | 显示全部楼层
jipolun 发表于 2021-11-14 22:12
所以 我发现
nx_tcp_socket_send()  无法在一个while 连续发送数据
因为测试发现会报(ox38)错误码

请问用的是哪个Echo Server? 0x38表明连接已经断开了,是不是服务器端主动断开的?可以通过Wireshark抓包来确认下。
回复

使用道具 举报

3

主题

9

回帖

18

积分

新手上路

积分
18
 楼主| 发表于 2021-11-15 17:06:21 | 显示全部楼层
catro 发表于 2021-11-15 09:27
请问用的是哪个Echo Server? 0x38表明连接已经断开了,是不是服务器端主动断开的?可以通过Wireshark抓包 ...

实际,我能确认没有断开喔
回复

使用道具 举报

1

主题

75

回帖

78

积分

初级会员

积分
78
发表于 2021-11-16 09:48:34 | 显示全部楼层
jipolun 发表于 2021-11-15 17:06
实际,我能确认没有断开喔

是否断开这个有很多含义:服务端网线没断,客户端网线没断,服务器端程序没显示断开,客户端程序没显示断开, 等等等。比较有效的方法是提供Wireshark或者tcpdump数据包用来分析网络情况。
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-5-21 18:19 , Processed in 0.665924 second(s), 27 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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