硬汉嵌入式论坛

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

[RL-TCPnet V7.X] 使用RL-TCPnet V7.X的函数netTCP_Connect反复重连服务器端,可以在前面调用下netTCP_Abort,保证每次都可以正常重连

[复制链接]

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106685
QQ
发表于 2022-1-4 13:32:01 | 显示全部楼层 |阅读模式


1.gif


  1. /*
  2. *********************************************************************************************************
  3. *
  4. *        模块名称 : TCPnet网络协议栈测试
  5. *        文件名称 : app_tcpnet_lib.c
  6. *        版    本 : V1.0
  7. *        说    明 : 测试的功能说明
  8. *              1. 强烈推荐将网线接到路由器或者交换机上面测试,因为已经使能了DHCP,可以自动获取IP地址。
  9. *              2. 客户端的例子相比服务器的例子稍麻烦些,因为客户端的例子需要用户知道电脑端IP和端口号。
  10. *                 并根据实际情况设置IP和端口号的宏定义,这个配置在文件app_tcpnet_lib.c开头,测试的时
  11. *                 候板子要连接这个IP和端口(下面是默认配置,一定要根据实际情况重新配置,如果不会配置,
  12. *                 看本例程对应的教程即可):
  13. *                 #define IP1            192
  14. *                 #define IP2            168
  15. *                 #define IP3            1
  16. *                 #define IP4            2                 
  17. *                 #define PORT_NUM       1001
  18. *              3. 创建了一个TCP Client,而且使能了局域网域名NetBIOS,用户只需在电脑端ping armfly
  19. *                 就可以获得板子的IP地址,本地端口被设置为1024。
  20. *              4. 用户可以在电脑端用网络调试软件创建TCP Server连接此客户端。
  21. *              5. 按键K1按下,发送8字节的数据给TCP Server。
  22. *              6. 按键K2按下,发送1024字节的数据给TCP Server。
  23. *              7. 按键K3按下,发送5MB字节的数据给TCP Server。
  24. *              8、摇杆OK键按下,连接远程服务器。
  25. *
  26. *        修改记录 :
  27. *                版本号   日期         作者        说明
  28. *                V1.0    2020-01-09   Eric2013     首发
  29. *
  30. *        Copyright (C), 2019-2030, 安富莱电子 www.armfly.com
  31. *
  32. *********************************************************************************************************
  33. */       
  34. #include "includes.h"       



  35. /*
  36. *********************************************************************************************************
  37. *                                          用于本文件的调试
  38. *********************************************************************************************************
  39. */
  40. #if 1
  41.         #define printf_debug printf
  42. #else
  43.         #define printf_debug(...)
  44. #endif


  45. /*
  46. *********************************************************************************************************
  47. *                                  宏定义,远程服务器的IP和端口
  48. *********************************************************************************************************
  49. */
  50. /* 要访问的远程服务器IP和端口配置,也就是电脑端调试助手设置的IP和端口号 */
  51. #define IP1            192
  52. #define IP2            168
  53. #define IP3            28
  54. #define IP4            146

  55. #define PORT_NUM         1001

  56. /* 这个是本地端口 */
  57. #define LocalPort_NUM    1024

  58. /*
  59. *********************************************************************************************************
  60. *                                             变量
  61. *********************************************************************************************************
  62. */
  63. NET_ADDR4 addr = { NET_ADDR_IP4, PORT_NUM, IP1,IP2,IP3,IP4};
  64. int32_t tcp_sock;


  65. /* TCPnet API的返回值 */
  66. static const char * ReVal_Table[]=
  67. {
  68.         "netOK: Operation succeeded",
  69.         "netBusy: Process is busy",
  70.         "netError: Unspecified error",
  71.         "netInvalidParameter: Invalid parameter specified",
  72.         "netWrongState: Wrong state error",
  73.         "netDriverError: Driver error",
  74.         "netServerError: Server error",
  75.         "netAuthenticationFailed: User authentication failed",
  76.         "netDnsResolverError: DNS host resolver failed",
  77.         "netFileError: File not found or file r/w error",
  78.         "netTimeout: Operation timeout",
  79. };

  80. /*
  81. *********************************************************************************************************
  82. *        函 数 名: tcp_cb_client
  83. *        功能说明: TCP Socket的回调函数
  84. *        形    参: socket  句柄
  85. *             event   事件类型
  86. *             addr    NET_ADDR类型变量,记录IP地址,端口号。
  87. *             buf     ptr指向的缓冲区记录着接收到的TCP数据。
  88. *             len     记录接收到的数据个数。
  89. *        返 回 值:
  90. *********************************************************************************************************
  91. */
  92. extern osThreadId_t ThreadIdTaskMsgPro;
  93. uint32_t tcp_cb_client (int32_t socket, netTCP_Event event,
  94.                         const NET_ADDR *addr, const uint8_t *buf, uint32_t len)
  95. {
  96.         switch (event)
  97.         {
  98.                 /*
  99.                         远程客户端连接消息
  100.                     1、数组ptr存储远程设备的IP地址,par中存储端口号。
  101.                     2、返回数值1允许连接,返回数值0禁止连接。
  102.                 */
  103.                 case netTCP_EventConnect:
  104.                         return (1);

  105.                 /* Socket远程连接已经建立 */
  106.                 case netTCP_EventEstablished:
  107.                         printf_debug("Socket is connected to remote peer\r\n");
  108.                         break;

  109.                 /* 连接断开 */
  110.                 case netTCP_EventClosed:
  111.                         osThreadFlagsSet(ThreadIdTaskMsgPro, KEY4_BIT3);
  112.                         printf_debug("Connection has been closed\r\n");
  113.                         break;

  114.                 /* 连接终止 */
  115.                 case netTCP_EventAborted:
  116.                         break;

  117.                 /* 发送的数据收到远程设备应答 */
  118.                 case netTCP_EventACK:
  119.                         break;

  120.                 /* 接收到TCP数据帧,ptr指向数据地址,par记录数据长度,单位字节 */
  121.                 case netTCP_EventData:
  122.                         printf_debug("Data length = %d\r\n", len);
  123.                         printf ("%.*s\r\n",len, buf);
  124.                         break;
  125.         }
  126.         return (0);
  127. }

  128. /*
  129. *********************************************************************************************************
  130. *        函 数 名: TCPnetTest
  131. *        功能说明: TCPnet应用
  132. *        形    参: 无
  133. *        返 回 值: 无
  134. *********************************************************************************************************
  135. */   
  136. void TCPnetTest(void)
  137. {
  138.         int32_t iCount;
  139.         uint8_t *sendbuf;
  140.         uint32_t maxlen;
  141.         netStatus res;
  142.         const uint16_t usMaxBlockTime = 2; /* 延迟周期 */
  143.         uint32_t EvtFlag;

  144.         tcp_sock = netTCP_GetSocket (tcp_cb_client);
  145.        
  146.         if (tcp_sock > 0)
  147.         {
  148.                 /* 使能TCP_TYPE_KEEP_ALIVE,会一直保持连接 */
  149.                 netTCP_SetOption (tcp_sock, netTCP_OptionKeepAlive, 1);               
  150.         }

  151.         while (1)
  152.         {
  153.                
  154.                 EvtFlag = osThreadFlagsWait(0x0000000FU, osFlagsWaitAny, usMaxBlockTime);
  155.                
  156.                 /* 按键消息的处理 */
  157.                 switch (EvtFlag)
  158.                 {
  159.                         /* 接收到K1键按下,给远程TCP客户端发送8字节数据 */
  160.                         case KEY1_BIT0:                          
  161.                                 iCount = 8;
  162.                                 if(netTCP_GetState(tcp_sock) == netTCP_StateESTABLISHED)
  163.                                 {
  164.                                         do
  165.                                         {
  166.                                                 if(netTCP_SendReady(tcp_sock) == true )
  167.                                                 {
  168.                                                         maxlen  = netTCP_GetMaxSegmentSize (tcp_sock);

  169.                                                         iCount -= maxlen;
  170.                                                        
  171.                                                         if(iCount < 0)
  172.                                                         {
  173.                                                                 /* 这么计算没问题的 */
  174.                                                                 maxlen = iCount + maxlen;
  175.                                                         }
  176.                                                        
  177.                                                         sendbuf = netTCP_GetBuffer (maxlen);
  178.                                                         sendbuf[0] = '1';
  179.                                                         sendbuf[1] = '2';
  180.                                                         sendbuf[2] = '3';
  181.                                                         sendbuf[3] = '4';
  182.                                                         sendbuf[4] = '5';
  183.                                                         sendbuf[5] = '6';
  184.                                                         sendbuf[6] = '7';
  185.                                                         sendbuf[7] = '8';
  186.                                                        
  187.                                                         /* 必须使用申请的内存空间 */
  188.                                                         netTCP_Send (tcp_sock, sendbuf, maxlen);
  189.                                                 }
  190.                                                
  191.                                         }while(iCount > 0);
  192.                                 }
  193.                                 break;

  194.                         /* 接收到K2键按下,给远程TCP客户端发送1024字节的数据 */
  195.                         case KEY2_BIT1:       
  196.                                 iCount = 1024;
  197.                                 if(netTCP_GetState(tcp_sock) == netTCP_StateESTABLISHED)
  198.                                 {
  199.                                         do
  200.                                         {
  201.                                                 if(netTCP_SendReady(tcp_sock) == true )
  202.                                                 {
  203.                                                         maxlen  = netTCP_GetMaxSegmentSize (tcp_sock);

  204.                                                         iCount -= maxlen;
  205.                                                        
  206.                                                         if(iCount < 0)
  207.                                                         {
  208.                                                                 /* 这么计算没问题的 */
  209.                                                                 maxlen = iCount + maxlen;
  210.                                                         }
  211.                                                        
  212.                                                         sendbuf = netTCP_GetBuffer (maxlen);
  213.                                                         sendbuf[0] = '1';
  214.                                                         sendbuf[1] = '2';
  215.                                                         sendbuf[2] = '3';
  216.                                                         sendbuf[3] = '4';
  217.                                                         sendbuf[4] = '5';
  218.                                                         sendbuf[5] = '6';
  219.                                                         sendbuf[6] = '7';
  220.                                                         sendbuf[7] = '8';
  221.                                                        
  222.                                                         /* 必须使用申请的内存空间 */
  223.                                                         netTCP_Send (tcp_sock, sendbuf, maxlen);
  224.                                                 }
  225.                                                
  226.                                         }while(iCount > 0);
  227.                                 }
  228.                                 break;                                       
  229.                                
  230.                                
  231.                         /* 接收到K3键按下,给远程TCP客户端发送5MB数据 */
  232.                         case KEY3_BIT2:                          
  233.                                 iCount = 5*1024*1024;       
  234.                                 if(netTCP_GetState(tcp_sock) == netTCP_StateESTABLISHED)
  235.                                 {
  236.                                         do
  237.                                         {
  238.                                                 if(netTCP_SendReady(tcp_sock) == true )
  239.                                                 {
  240.                                                         maxlen  = netTCP_GetMaxSegmentSize (tcp_sock);

  241.                                                         iCount -= maxlen;
  242.                                                        
  243.                                                         if(iCount < 0)
  244.                                                         {
  245.                                                                 /* 这么计算没问题的 */
  246.                                                                 maxlen = iCount + maxlen;
  247.                                                         }
  248.                                                        
  249.                                                         sendbuf = netTCP_GetBuffer (maxlen);
  250.                                                         sendbuf[0] = '1';
  251.                                                         sendbuf[1] = '2';
  252.                                                         sendbuf[2] = '3';
  253.                                                         sendbuf[3] = '4';
  254.                                                         sendbuf[4] = '5';
  255.                                                         sendbuf[5] = '6';
  256.                                                         sendbuf[6] = '7';
  257.                                                         sendbuf[7] = '8';
  258.                                                        
  259.                                                         /* 必须使用申请的内存空间 */
  260.                                                         netTCP_Send (tcp_sock, sendbuf, maxlen);
  261.                                                 }
  262.                                                
  263.                                         }while(iCount > 0);
  264.                                 }
  265.                                 break;
  266.                        
  267.                         /* 接收到摇杆OK键按下,连接远程服务器 */
  268.                         case KEY4_BIT3:                          
  269.                                 if (tcp_sock > 0)
  270.                                 {
  271.                                         if(netTCP_GetState(tcp_sock) != netTCP_StateESTABLISHED)
  272.                                         {
  273.                                             netTCP_Abort(tcp_sock);
  274.                                                 res = netTCP_Connect (tcp_sock, (NET_ADDR *)&addr, LocalPort_NUM);
  275.                                                 printf_debug("%s\r\n", ReVal_Table[res]);
  276.                                         }
  277.                                 }
  278.                                 break;
  279.                                
  280.                          /* 其他的键值不处理 */
  281.                         default:                     
  282.                                 break;
  283.                 }
  284.         }
  285. }

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


回复

使用道具 举报

0

主题

30

回帖

30

积分

新手上路

积分
30
发表于 2022-11-7 01:19:11 | 显示全部楼层
硬汉哥,电脑端删除连接,或者断开客户端连接,板子端如果为Abort,复位马上能连接上,如果为Closed,复位也连接不上,这两个有啥不同吗?
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106685
QQ
 楼主| 发表于 2022-11-7 17:00:47 | 显示全部楼层
BruceWang 发表于 2022-11-7 01:19
硬汉哥,电脑端删除连接,或者断开客户端连接,板子端如果为Abort,复位马上能连接上,如果为Closed,复位 ...

就是要abort,不能close,这个精髓测试,我花了半天才测试出来的api
回复

使用道具 举报

12

主题

176

回帖

212

积分

高级会员

积分
212
发表于 2022-11-7 22:33:54 来自手机 | 显示全部楼层
请问硬汉 abort 之后应该怎么处理呢?删除本任务、清理网络再initialize吗?
回复

使用道具 举报

0

主题

30

回帖

30

积分

新手上路

积分
30
发表于 2022-11-8 01:36:31 | 显示全部楼层
eric2013 发表于 2022-11-7 17:00
就是要abort,不能close,这个精髓测试,我花了半天才测试出来的api

硬汉哥,可能是我表述不清晰,您那边理解有偏差;
1,想问一下硬汉哥测试环境是怎样子?电脑<----网线---->板子,是这样子吗?
2、我的测试环境是,电脑<---网线-----交换机-----网线---->板子。
3、操作:我每次在电脑端,不管是《删除客户端连接》,还是《断开客户端连接》,板子端串口都会打印:TCP   connection Closed,而不是TCP connection Abort;即每次板子端都会进入netTCP_EventClosed事件,而不是进入netTCP_EventAborted;
4、以上就是我和硬汉个测试出现的不同之处,不知是啥原因导致,可能是接了交换机的原因(但没有验证过)
5、如果串口打印Abort,板子能立马连接上,如果打印Closed,则需要很久
6、针对Closed这种情况,硬汉哥有没有什么好的办法解决,大家可以讨论一下
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106685
QQ
 楼主| 发表于 2022-11-8 09:45:36 | 显示全部楼层
gallop020142 发表于 2022-11-7 22:33
请问硬汉 abort 之后应该怎么处理呢?删除本任务、清理网络再initialize吗?

重连就行了。
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106685
QQ
 楼主| 发表于 2022-11-8 09:49:40 | 显示全部楼层
BruceWang 发表于 2022-11-8 01:36
硬汉哥,可能是我表述不清晰,您那边理解有偏差;
1,想问一下硬汉哥测试环境是怎样子?电脑板子,是这 ...

楼主位的是通过路由器或者交换机接外网服务器的实际应用案例,

实际应用中,服务器端有个连接时间限制,超过后自动断开。

断开后,客户端直接下abort后,然后重连就可以及时连接上,如果不加会比较随机,有时候时间很长。
回复

使用道具 举报

0

主题

30

回帖

30

积分

新手上路

积分
30
发表于 2022-11-8 12:30:02 | 显示全部楼层
eric2013 发表于 2022-11-8 09:49
楼主位的是通过路由器或者交换机接外网服务器的实际应用案例,

实际应用中,服务器端有个连接时间限制 ...

硬汉哥,问题找到了,只要不重新申请Socket,就没有问题了,一直判断当前连接状态即可
[C] 纯文本查看 复制代码
while(1)
		{
			if(netTCP_GetState(SSEI_TCP_Socket) != netTCP_StateESTABLISHED)
			{
				netTCP_Abort(SSEI_TCP_Socket);
				
				ret = netTCP_Connect (SSEI_TCP_Socket, (NET_ADDR *)&ServerAddr, LOCAL_PORT_NUM);
				
				Printf_task("%s\r\n", errSSEI_NetRetVal_Table[ret]);
			}

			osDelay(50);
		}
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106685
QQ
 楼主| 发表于 2022-11-9 13:00:31 | 显示全部楼层
BruceWang 发表于 2022-11-8 12:30
硬汉哥,问题找到了,只要不重新申请Socket,就没有问题了,一直判断当前连接状态即可
[mw_shl_code=c,t ...

好的。
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-4-29 18:04 , Processed in 0.268089 second(s), 36 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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