硬汉嵌入式论坛

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

[RL-TCPnet] BSD socket方式连接服务器不能连接问题

[复制链接]

25

主题

100

回帖

180

积分

初级会员

积分
180
发表于 2018-8-8 15:34:36 | 显示全部楼层 |阅读模式
板子做client端,创建两个任务连接task1 task2,task连接10000端口的服务器1,task2连接10001的服务器2,现在出现的问题是,如果上电直接运行,会造成两个客户端都无法连接,在线监测发现通过socket申请的端口号都一样,只要在两个任务里分别设置一个断点就能连接上了。不然两个服务器都无法连接或者偶尔能连接上,但两个客户端都连接的同一个服务器,但在程序了每个任务都指定了不同的端口号的服务器。请问一下这个应该是什么问题?
  1. #include "bsp_net.h"
  2. #include "bsp_json.h"
  3. #include "string.h"

  4. int sock1;
  5. SOCKADDR_IN addr1;
  6. int sock2;
  7. SOCKADDR_IN addr2;
  8. /*
  9. *********************************************************************************************************
  10. *        函 数 名: vTaskSocket10001
  11. *        功能说明: 控制通信任务
  12. *        形    参: 无
  13. *        返 回 值: 无
  14. *********************************************************************************************************
  15. */
  16. void vTaskSocket10001(void *arg)
  17. {
  18.         char sendbuf[500] = {0};
  19.         uint8_t recvbuf[500] = {0};
  20.         uint8_t cmd = 0,i;
  21.         uint16_t len = 0;
  22.         int  res;
  23.         unsigned long sck_mode = 1;
  24.        
  25.         while (1)                                                                                                        //客户端断开可以在重新进行连接
  26.         {
  27.                 sock1 = socket (AF_INET, SOCK_STREAM, 0);
  28.                 res = ioctlsocket (sock1, FIO_KEEP_ALIVE, &sck_mode);        /* 设置使能KEEP ALIVE,让客户端和服务器保存连接 */
  29.                 addr1.sin_port = htons(8089);                                                        /* 端口号设置为1001 */
  30.                 addr1.sin_family = PF_INET;                                                                /* 与函数socket中的AF_INET作用一样 */
  31.                 addr1.sin_addr.s_b1 = server_ip1;
  32.                 addr1.sin_addr.s_b2 = server_ip2;
  33.                 addr1.sin_addr.s_b3 = server_ip3;
  34.                 addr1.sin_addr.s_b4 = server_ip4;
  35.                 res = connect (sock1, (SOCKADDR *)&addr1, sizeof (addr1));        /* 客户端连接远程服务器,如果远程服务器还未创建,此函数会立即返回 */
  36.                 while (1)
  37.                 {
  38.                         res = recv (sock1, (char *)recvbuf, sizeof(recvbuf), 0);
  39.                         if (res <= 0)
  40.                         {
  41.                                 if((res == SCK_EINVALID) || (res == SCK_ECLOSED))
  42.                                 {
  43.                                         goto err;
  44.                                 }
  45.                         }
  46.                         else
  47.                         {
  48.                                 cmd = control_treatment(recvbuf);                                //解析接收到的数据
  49.                                 len = control_generation(sendbuf,cmd);                        //根据接收的数据进行返回数据
  50.                                 again:
  51.                                 res = send (sock1, (char *)sendbuf, len,0);//+14+2, 0);
  52.                                 if (res < 0)
  53.                                 {
  54.                                         //sock句柄无效        sock已经关闭了                底层通信出错
  55.                                         if((res == SCK_EINVALID)||(res == SCK_ECLOSED)||(res == SCK_ERROR))
  56.                                         {
  57.                                                 goto err;
  58.                                         }
  59.                                         else//非以上必须重连的情况,直接进行重发,后期可以优化针对阻塞才重发
  60.                                         {
  61.                                                 goto again;
  62.                                         }
  63.                                 }
  64.                         }
  65.                         vTaskDelay(10);
  66.                 }
  67.                 err:
  68.                 while(1)//释放sock失败需要重新的调用,所以做循环处理
  69.                 {
  70.                         if(closesocket (sock1) != SCK_EWOULDBLOCK)
  71.                                 break;
  72.                        
  73.                         vTaskDelay(1000);
  74.                 }
  75.                 vTaskDelay(2000);
  76.         }
  77. }

  78. /*
  79. *********************************************************************************************************
  80. *        函 数 名: vTaskSocket10000
  81. *        功能说明: 实时传输数据通信任务
  82. *        形    参: 任务传递参数
  83. *        返 回 值: 本任务内需要用到一些sock等参数,直接全部在内部进行封装处理数据
  84. *********************************************************************************************************
  85. */
  86. void vTaskSocket10000(void *arg)
  87. {

  88.         int  res;                                                                                //send recv函数使用
  89.         unsigned long sck_mode;
  90.        
  91.         while (1)
  92.         {
  93.                 sock2 = socket (AF_INET, SOCK_STREAM, 0);
  94.                 sck_mode = 1;
  95.                 res = ioctlsocket (sock2, FIO_KEEP_ALIVE, &sck_mode);
  96.                 if (res == SCK_SUCCESS)
  97.                 {
  98.                 }
  99.                 else
  100.                 {
  101.                 }
  102.                 addr2.sin_port = htons(8089);/* 端口号设置为1001 */
  103.                 addr2.sin_family = PF_INET;/* 与函数socket中的AF_INET作用一样 */
  104.                 addr2.sin_addr.s_b1 = server_ip1;
  105.                 addr2.sin_addr.s_b2 = server_ip2;
  106.                 addr2.sin_addr.s_b3 = server_ip3;
  107.                 addr2.sin_addr.s_b4 = server_ip4;
  108.                 res = connect (sock2, (SOCKADDR *)&addr2, sizeof (addr2));/* 客户端连接远程服务器,如果远程服务器还未创建,此函数会立即返回 */
  109.                 while (1)
  110.                 {
  111.                         if(Parameter_Setting.RunStop == true)
  112.                         {

  113.                                         res = send (sock2, (const char *)sendbuf, len, 0);
  114.                                         if (res < 0)//发送失败的情况
  115.                                         {
  116.                                                 //sock句柄无效        sock已经关闭了                底层通信出错
  117.                                                 if((res == SCK_EINVALID)||(res == SCK_ECLOSED)||(res == SCK_ERROR))
  118.                                                 {
  119.                                                         goto err;
  120.                                                 }

  121.                                         res = recv (sock2, recvbuf, sizeof(recvbuf), 0);        //接收数据
  122.                                         if (res <= 0)
  123.                                         {
  124.                                                 //同上发送出错机制
  125.                                                 if((res == SCK_EINVALID) || (res == SCK_ECLOSED))
  126.                                                 {       
  127.                                                         goto err;                                                                //出错后直接通过goto跳转       
  128.                                                 }
  129.                                         }
  130.                                 }
  131.                         }
  132.                         else//非运行状态,发送心跳
  133.                         {
  134.                                 sprintf((char *)sendbuf->buf,"{"Cmd":0,"Sync":%d}",sync_con_1++);
  135.                                 again_stop:                                        //发送数据有时会存在失败,用goto进行重发
  136.                                 len = strlen((const char *)sendbuf->buf);//计算发送数据的长度,后期把send的函数的长度进行增加头尾长度暂时未加
  137. //                                sendbuf->buf[len] = 0xee;
  138. //                                sendbuf->buf[len+1] = 0xee;
  139.                                 res = send (sock2, (const char *)sendbuf, len, 0);
  140.                                 if (res < 0)//发送失败的情况
  141.                                 {
  142.                                         //sock句柄无效        sock已经关闭了                底层通信出错
  143.                                         if((res == SCK_EINVALID)||(res == SCK_ECLOSED)||(res == SCK_ERROR))
  144.                                         {
  145.                                                 goto err;
  146.                                         }
  147.                                         else//非以上必须重连的情况,直接进行重发,后期可以优化针对阻塞才重发
  148.                                         {
  149.                                                 goto again_stop;
  150.                                         }
  151.                                 }
  152.                                 else//发送成功
  153.                                 {               
  154.                                        
  155.                                 }
  156.                                 res = recv (sock2, recvbuf, sizeof(recvbuf), 0);        //接收数据
  157.                                 if (res <= 0)
  158.                                 {
  159.                                         //同上发送出错机制
  160.                                         if((res == SCK_EINVALID) || (res == SCK_ECLOSED))
  161.                                         {       
  162.                                                 goto err;                                                                //出错后直接通过goto跳转       
  163.                                         }
  164.                                 }
  165.                         }
  166.                         vTaskDelay(5000);
  167.                 }       
  168.                 err:
  169.                 while(1)//关闭sock失败时要重复调用
  170.                 {
  171.                         if(closesocket (sock2) != SCK_EWOULDBLOCK)
  172.                                 break;
  173.                         vTaskDelay(500);
  174.                 }
  175.                 vTaskDelay(1000);
  176.         }
  177. }

  178. /*
  179. *********************************************************************************************************
  180. *        函 数 名: vTaskTCPnet
  181. *        功能说明: RL-TCPnet网络主任务
  182. *        形    参: pvParameters 是在创建该任务时传递的形参
  183. *        返 回 值: 无
  184. *   优 先 级: 5  
  185. *********************************************************************************************************
  186. */
  187. void vTaskTCPnet(void *arg)
  188. {
  189.     while(1)
  190.     {
  191.                 /* RL-TCPnet处理函数 */
  192.                 xEventGroupWaitBits(xCreatedTCPnetGroup, /* 事件标志组句柄 */
  193.                                                         0x0001,              /* 等待被设置 */
  194.                                                         pdTRUE,              /* 退出前bit0被清除 */
  195.                                                         pdFALSE,             /* 设置为pdFALSE表示仅等待bit0被设置*/
  196.                                                         portMAX_DELAY);          /* 永久等待 */
  197.                
  198.                 while (main_TcpNet() == __TRUE);
  199.     }
  200. }

  201. /*********************************************************************************************************
  202. *        函 数 名: vTaskStart
  203. *        功能说明: 启动任务,也是最高优先级任务,这里实现RL-TCPnet的时间基准更新
  204. *        形    参: pvParameters 是在创建该任务时传递的形参
  205. *        返 回 值: 无
  206. *   优 先 级: 5  
  207. *********************************************************************************************************
  208. */
  209. void vTaskTCPStart(void *arg)
  210. {
  211.         TickType_t xLastWakeTime;
  212.         const TickType_t xFrequency = 100;
  213.        
  214.         /* 初始化RL-TCPnet */
  215.         init_TcpNet ();
  216.        
  217.         /* 获取当前的系统时间 */
  218.     xLastWakeTime = xTaskGetTickCount();
  219.        
  220.     while(1)
  221.     {       
  222.                 /* RL-TCPnet时间基准更新函数 */
  223.                 timer_tick ();

  224.                 xEventGroupSetBits(xCreatedTCPnetGroup, 0x0001);
  225.                
  226.                 /* vTaskDelayUntil是绝对延迟,vTaskDelay是相对延迟。*/
  227.         vTaskDelayUntil(&xLastWakeTime, xFrequency);
  228.     }
  229. }
复制代码
部分代码删除了一点,但整体的是根据老大的例子写的
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107488
QQ
发表于 2018-8-8 17:56:41 | 显示全部楼层
使用RTX版本的例子,测试下看看,使用FreeRTOS的话,因为是我自己做的底层多任务互斥机制,估计有不完善的地方。

你使用RTX看看。
回复

使用道具 举报

25

主题

100

回帖

180

积分

初级会员

积分
180
 楼主| 发表于 2018-8-8 15:47:36 | 显示全部楼层
不知道是不是这个问题,在connet之后,一般会返回-4错误,在connect之后做个延时就可以正常连接上了,可能还是别的地方原因
回复

使用道具 举报

25

主题

100

回帖

180

积分

初级会员

积分
180
 楼主| 发表于 2018-8-8 20:54:23 | 显示全部楼层
eric2013 发表于 2018-8-8 17:56
使用RTX版本的例子,测试下看看,使用FreeRTOS的话,因为是我自己做的底层多任务互斥机制,估计有不完善的 ...

使用RTX完美没问题,溜溜的
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107488
QQ
发表于 2018-8-9 00:01:44 | 显示全部楼层
xujun 发表于 2018-8-8 20:54
使用RTX完美没问题,溜溜的

回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-6-4 06:43 , Processed in 0.277354 second(s), 27 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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