硬汉嵌入式论坛

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

[ThreadX全家桶] 新整理的ThreadX NetXDUO的TCP服务器测试代码详细注释版

  [复制链接]

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107667
QQ
发表于 2021-12-20 02:17:27 | 显示全部楼层 |阅读模式


例子下载:
Vx - 2402
https://www.armbbs.cn/forum.php?mod=viewthread&tid=104619

  1. /*
  2. *********************************************************************************************************
  3. *
  4. *        模块名称 : 网络协议栈测试
  5. *        文件名称 : demo_dm9162_netx.c
  6. *        版    本 : V1.0
  7. *        说    明 : 测试的功能说明
  8. *              1. 默认IP地址192.168.28.245,在本文件配置,用户可根据需要修改。
  9. *              2. 可以在电脑端用网络调试软件创建TCP Client连接此服务器端,端口号1001。
  10. *              3. 实现了一个简单的回环通信,用户使用上位机发送的数据通过板子返回到上位机。
  11. *
  12. *        修改记录 :
  13. *                版本号   日期         作者        说明
  14. *                V1.0    2021-01-30   Eric2013     首发
  15. *
  16. *        Copyright (C), 2018-2030, 安富莱电子 www.armfly.com
  17. *
  18. *********************************************************************************************************
  19. */       
  20. #include "includes.h"       



  21. /*
  22. *********************************************************************************************************
  23. *                                            IP相关
  24. *********************************************************************************************************
  25. */
  26. #define DEFAULT_PORT                    1001    /* TCP服务器监听端口号 */

  27. #define IP_ADDR0                        192
  28. #define IP_ADDR1                        168
  29. #define IP_ADDR2                        28
  30. #define IP_ADDR3                        245

  31. #define  MAX_TCP_CLIENTS                1

  32. /*
  33. *********************************************************************************************************
  34. *                                            NetX任务和通信组件
  35. *********************************************************************************************************
  36. */
  37. /* 上电先将其设置到低优先级,待网线插入后提升优先级到3 */
  38. #define  APP_CFG_TASK_NETX_PRIO                           28u   
  39. #define  APP_CFG_TASK_NETX_STK_SIZE                     4096u
  40. static   uint64_t  AppTaskNetXStk[APP_CFG_TASK_NETX_STK_SIZE/8];

  41. /* 提升NetX处理任务优先级到3 */
  42. #define  APP_CFG_TASK_NETX_PRIO1                           3u

  43. /* 提升NetX应用任务优先级到6 */
  44. #define  APP_CFG_TASK_NetXPro_PRIO1                        6u

  45. NX_TCP_SOCKET TCPSocket;
  46. TX_SEMAPHORE  Semaphore;


  47. /*
  48. *********************************************************************************************************
  49. *                                            NetX任务和通信组件
  50. *********************************************************************************************************
  51. */
  52. UCHAR data_buffer[4096];

  53. NX_PACKET_POOL    pool_0;
  54. NX_IP             ip_0;  

  55. /* 数据包内存池 */
  56. #define PACKET_SIZE          1536
  57. #define NX_PACKET_POOL_SIZE  ((PACKET_SIZE + sizeof(NX_PACKET)) * 20)
  58.        
  59. ULONG  packet_pool_area[NX_PACKET_POOL_SIZE/4 + 4];

  60. /* ARP缓存 */
  61. ULONG    arp_space_area[512 / sizeof(ULONG)];                                                      
  62. ULONG    error_counter;

  63. #define PRINT_DATA(addr, port, data)        do {                                            \
  64.                                                   printf("[%lu.%lu.%lu.%lu:%u] -> '%s' \r\n", \
  65.                                                   (addr >> 24) & 0xff,                      \
  66.                                                   (addr >> 16) & 0xff,                      \
  67.                                                   (addr >> 8) & 0xff,                       \
  68.                                                   (addr & 0xff), port, data);               \
  69.                                                } while(0)

  70. extern TX_THREAD   AppTaskNetXProTCB;
  71. extern TX_THREAD   *netx_thread_ptr;                                               
  72. extern VOID  nx_driver_stm32h7xx(NX_IP_DRIVER *driver_req_ptr);
  73.   
  74.                                                
  75. /*
  76. *********************************************************************************************************
  77. *        函 数 名: NetXTest
  78. *        功能说明: TCPnet应用
  79. *        形    参: 无
  80. *        返 回 值: 无
  81. *********************************************************************************************************
  82. */   
  83. void NetXTest(void)
  84. {
  85.     UINT status;
  86.     UINT ret;
  87.     ULONG socket_state;
  88.     UINT old_priority;

  89.     NX_PACKET *data_packet;
  90.     ULONG bytes_read;
  91.        
  92.         ULONG peer_ip_address;
  93.         ULONG peer_port;
  94.    
  95.        
  96.     /* 初始化NetX */
  97.     nx_system_initialize();

  98.     /* 创建内存池 */
  99.     status =  nx_packet_pool_create(&pool_0,                                       /* 内存池控制块 */
  100.                                      "NetX Main Packet Pool",                      /* 内存池名 */
  101.                                      1536,                                         /* 内存池每个数据包大小,单位字节
  102.                                                                                       此值必须至少为 40 个字节,并且还必须可以被 4 整除 */
  103.                                                                          (ULONG*)(((int)packet_pool_area + 15) & ~15) ,/* 内存池地址,此地址必须ULONG对齐 */
  104.                                      NX_PACKET_POOL_SIZE);                         /* 内存池大小 */                  
  105.          
  106.     /* 检测创建是否失败 */
  107.     if (status) error_counter++;

  108.     /* 例化IP */
  109.     status = nx_ip_create(&ip_0,                                                   /* IP实例控制块 */                                    
  110.                             "NetX IP Instance 0",                                  /* IP实例名 */     
  111.                             IP_ADDRESS(IP_ADDR0, IP_ADDR1, IP_ADDR2, IP_ADDR3),    /* IP地址 */
  112.                             0xFFFFFF00UL,                                          /* 子网掩码 */
  113.                             &pool_0,                                               /* 内存池 */
  114.                                                         nx_driver_stm32h7xx,                                   /* 网卡驱动 */
  115.                             (UCHAR*)AppTaskNetXStk,                                /* IP任务栈地址 */
  116.                             sizeof(AppTaskNetXStk),                                /* IP任务栈大小,单位字节 */
  117.                             APP_CFG_TASK_NETX_PRIO);                               /* IP任务优先级 */
  118.                            
  119.             
  120.     /* 检测创建是否失败 */
  121.     if (status) error_counter++;

  122.     /* 使能ARP,并提供ARP缓存 */
  123.     status =  nx_arp_enable(&ip_0,                     /* IP实例控制块 */
  124.                                                         (void *)arp_space_area,    /* ARP缓存地址 */
  125.                                                         sizeof(arp_space_area));   /* 每个 ARP 条目均为 52 个字节,因此,ARP 条目总数是52字节整数倍 */

  126.     /* 使能fragment */   
  127.     status = nx_ip_fragment_enable(&ip_0);

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

  130.     /* 使能TCP */
  131.     status =  nx_tcp_enable(&ip_0);

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

  134.     /* 使能UDP  */
  135.     status =  nx_udp_enable(&ip_0);

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

  138.     /* 使能ICMP */
  139.     status =  nx_icmp_enable(&ip_0);

  140.     /* 检测使能成功 */
  141.     if (status) error_counter++;   
  142.    
  143.     /* NETX初始化完毕后,重新设置优先级 */
  144.     tx_thread_priority_change(netx_thread_ptr, APP_CFG_TASK_NETX_PRIO1, &old_priority);
  145.     tx_thread_priority_change(&AppTaskNetXProTCB, APP_CFG_TASK_NetXPro_PRIO1, &old_priority);
  146.    
  147.     ////////////////////////////////////////////////////////////////////////////////////////////////
  148.     /* 创建TCP Socket */
  149.     ret = nx_tcp_socket_create(&ip_0,                 /* IP实例控制块 */   
  150.                                &TCPSocket,            /* TCP控制块 */
  151.                                "TCP Server Socket",   /* TCP Socket名 */
  152.                                NX_IP_NORMAL,          /* IP服务类型 */
  153.                                NX_FRAGMENT_OKAY,      /* 使能IP分段 */
  154.                                NX_IP_TIME_TO_LIVE,    /* 指定一个 8 位的值,用于定义此数据包在被丢弃之前可通过的路由器数目 */
  155.                                4320,                  /* TCP Socket接收队列中允许的最大字节数 */
  156.                                NX_NULL,               /* 用于在接收流中检测到紧急数据时调用的回调函数 */
  157.                                NX_NULL);              /* TCP Socket另一端发出断开连接时调用的回调函数 */
  158.     if (ret)
  159.     {
  160.                 Error_Handler(__FILE__, __LINE__);   
  161.     }

  162.     /*
  163.     * 监听新的链接。
  164.     * 创建回调TCP_listen_callback表示监听到新连接。
  165.     */
  166.     ret = nx_tcp_server_socket_listen(&ip_0,                  /* IP实例控制块 */  
  167.                                                                           DEFAULT_PORT,           /* 默认端口 */         
  168.                                           &TCPSocket,             /* TCP Socket控制块 */
  169.                                           MAX_TCP_CLIENTS,        /* 可以监听的连接数 */
  170.                                           NULL);                                     /* 监听回调函数 */

  171.     if (ret)
  172.     {
  173.         Error_Handler(__FILE__, __LINE__);
  174.     }

  175.         /* 启动TCP通信前,接收新连接 */
  176.         ret = nx_tcp_server_socket_accept(&TCPSocket,         /* TCP Socket控制块 */
  177.                                            TX_WAIT_FOREVER);  /* 监听回调函数 */

  178.         if (ret)
  179.         {
  180.                 Error_Handler(__FILE__, __LINE__);
  181.         }

  182.    
  183.         while(1)
  184.         {
  185.         TX_MEMSET(data_buffer, '\0', sizeof(data_buffer));

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

  199.         /* 如果连接还没有建立,继续接受新连接,成功的话开启接收数据 */
  200.         if(socket_state != NX_TCP_ESTABLISHED)
  201.         {
  202.                         /* 启动TCP通信前,接收新连接 */
  203.                         ret = nx_tcp_server_socket_accept(&TCPSocket,       /* TCP Socket控制块 */
  204.                                                           TX_WAIT_FOREVER); /* 等待连接 */

  205.                         if (ret)
  206.                         {
  207.                                 Error_Handler(__FILE__, __LINE__);
  208.                         }
  209.         }
  210.         
  211.         if((socket_state == NX_TCP_ESTABLISHED)&&(ret == NX_SUCCESS))
  212.         {
  213.                
  214.             /* 接收TCP客户端发的TCP数据包 */
  215.             ret = nx_tcp_socket_receive(&TCPSocket,        /* TCP Socket控制块 */
  216.                                                     &data_packet,      /* 接收到的数据包 */
  217.                                                     NX_WAIT_FOREVER);  /* 永久等待 */

  218.             if (ret == NX_SUCCESS)
  219.             {
  220.                
  221.                                 /* 获取客户端的IP地址和端口 */
  222.                                 nx_tcp_socket_peer_info_get(&TCPSocket,       /* TCP Socket控制块 */
  223.                                                                                         &peer_ip_address, /* 远程IP地址 */
  224.                                                                                         &peer_port);      /* 远程端口号 */

  225.                 /* 获取客户端发来的数据 */
  226.                 nx_packet_data_retrieve(data_packet,    /* 接收到的数据包 */
  227.                                                         data_buffer,    /* 解析出数据 */
  228.                                                         &bytes_read);   /* 数据大小 */

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

  231.                 /* 立即将接收到的数据发送回去 */
  232.                 ret =  nx_tcp_socket_send(&TCPSocket,       /* TCP Socket控制块 */
  233.                                                           data_packet,      /* 数据包 */
  234.                                                           NX_WAIT_FOREVER); /* 永久等待 */
  235.             }
  236.             else
  237.             {
  238.                 /* 断开连接 */
  239.                 nx_tcp_socket_disconnect(&TCPSocket,
  240.                                                          NX_WAIT_FOREVER);
  241.                                
  242.                                 /* 解除Socket和服务器端口的绑定 */
  243.                 nx_tcp_server_socket_unaccept(&TCPSocket);
  244.                                
  245.                                 /* 重新监听 */
  246.                 nx_tcp_server_socket_relisten(&ip_0,
  247.                                                               DEFAULT_PORT,
  248.                                                               &TCPSocket);
  249.             }
  250.         }
  251.         }         
  252. }

  253. /***************************** 安富莱电子 www.armfly.com (END OF FILE) *********************************/
复制代码



回复

使用道具 举报

3

主题

1259

回帖

1268

积分

至尊会员

积分
1268
发表于 2021-12-20 08:49:30 | 显示全部楼层
硬汉大哥,支持组播的话,要加哪个初始化啊?谢谢
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107667
QQ
 楼主| 发表于 2021-12-20 08:55:38 | 显示全部楼层
morning_enr6U 发表于 2021-12-20 08:49
硬汉大哥,支持组播的话,要加哪个初始化啊?谢谢

没用过
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107667
QQ
 楼主| 发表于 2021-12-20 08:59:51 | 显示全部楼层
morning_enr6U 发表于 2021-12-20 08:49
硬汉大哥,支持组播的话,要加哪个初始化啊?谢谢

看了下手册,这个就是
QQ截图20211220085850.png
回复

使用道具 举报

1

主题

75

回帖

78

积分

初级会员

积分
78
发表于 2021-12-20 15:11:18 | 显示全部楼层
如果不需要IGMP功能的话,推荐使用这个接口nx_ipv4_multicast_interface_join
回复

使用道具 举报

3

主题

1259

回帖

1268

积分

至尊会员

积分
1268
发表于 2021-12-20 15:49:34 | 显示全部楼层
感谢硬汉大哥,和catro大哥的热心回复,有机会尝试的时候,发测试结果上来。
回复

使用道具 举报

3

主题

1259

回帖

1268

积分

至尊会员

积分
1268
发表于 2021-12-20 15:52:19 | 显示全部楼层
  1. UINT nx_ipv4_multicast_interface_join(
  2.     NX_IP *ip_ptr,
  3.     ULONG group_address,
  4.     UINT interface_index);
复制代码
Description
This service joins an IP instance to the specified multicast group via a specified network interface. Once the IP instance joins a multicast group, the IP receive logic starts to forward data packets from the give multicast group to the upper layer. Note that this service joins a multicast group without sending IGMP reports.

回复

使用道具 举报

2

主题

21

回帖

27

积分

新手上路

积分
27
发表于 2021-12-23 16:42:58 | 显示全部楼层
NetX duo 不用Threadx操作系统
能单独移植吗?
回复

使用道具 举报

2

主题

21

回帖

27

积分

新手上路

积分
27
发表于 2021-12-23 16:44:04 | 显示全部楼层
这个协议栈能单独移植吗?不加Threadx操作系统
回复

使用道具 举报

24

主题

122

回帖

194

积分

初级会员

积分
194
发表于 2021-12-23 17:39:15 来自手机 | 显示全部楼层
应该是不行,二者耦合度很高
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107667
QQ
 楼主| 发表于 2021-12-24 01:26:24 | 显示全部楼层
lixuanyi 发表于 2021-12-23 16:42
NetX duo 不用Threadx操作系统
能单独移植吗?

肯定是可以的,但是有点繁琐,上电有专门的IP任务要刷。后面他们官方提供个封装层更简单。
回复

使用道具 举报

1

主题

75

回帖

78

积分

初级会员

积分
78
发表于 2021-12-24 12:35:26 | 显示全部楼层
暂时不行,NetX Duo用到了一些ThreadX的内部功能来实现快速阻塞和唤醒
回复

使用道具 举报

2

主题

21

回帖

27

积分

新手上路

积分
27
发表于 2021-12-30 11:28:16 | 显示全部楼层
eric2013 发表于 2021-12-24 01:26
肯定是可以的,但是有点繁琐,上电有专门的IP任务要刷。后面他们官方提供个封装层更简单。

感谢,也就是Threadx的一些组件与其操作系统的耦合度比较高的,不建议单独移植使用,是吧。
回复

使用道具 举报

1

主题

75

回帖

78

积分

初级会员

积分
78
发表于 2022-1-4 09:50:44 | 显示全部楼层
lixuanyi 发表于 2021-12-30 11:28
感谢,也就是Threadx的一些组件与其操作系统的耦合度比较高的,不建议单独移植使用,是吧。

不全是, 部分组件是可以脱离ThreadX使用的,比如GUIX, FileX, LevelX以及crypto
回复

使用道具 举报

2

主题

14

回帖

20

积分

新手上路

积分
20
发表于 2022-9-9 14:05:59 | 显示全部楼层
硬汉哥,我第一次下载程序的时候是可以创建tcp server的,然后数据传输的时候tcp断了,现在调用nx_tcp_server_socket_accept返回的是0x38,用户手册里面没有这个返回值
回复

使用道具 举报

1

主题

75

回帖

78

积分

初级会员

积分
78
发表于 2022-9-9 14:39:41 | 显示全部楼层
这个错误是NX_NOT_CONNECTED
回复

使用道具 举报

2

主题

14

回帖

20

积分

新手上路

积分
20
发表于 2022-9-9 15:52:28 | 显示全部楼层
catro 发表于 2022-9-9 14:39
这个错误是NX_NOT_CONNECTED

嗯嗯,谢谢
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-6-11 12:52 , Processed in 0.346902 second(s), 28 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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