硬汉嵌入式论坛

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

[有问必答] 关于 RL-TCPnet BSD Socket 的问题求教

[复制链接]

3

主题

4

回帖

45

积分

新手上路

积分
45
发表于 2018-6-26 10:57:15 | 显示全部楼层 |阅读模式
你好,

STM32 F407   RL-TCPnet 网络协议栈 , 基于 BSD SOCKET 开发 服务端应用 , 下面 端口绑定、监听部分,仅调用一次。 上位机建立连接之后端开, 然后再次连接(IP一样,端口不一样),请问下此时不需要 accept 就能自动连接?  
此外, 连接的 iIndex 并没有再次更新,  但是 recv (iIndex, szBuffer, sizeof(szBuffer), 0);   和  send (iIndex, (char *)szBuffer, iLen, 0);  却都能正常工作,收发数据完全正常!

谢谢!


          int sock, sd, len;
          SOCKADDR_IN addr1, addr2;
          pdata = pdata;
          sock = socket (AF_INET, SOCK_STREAM, 0);
       
          addr1.sin_port        = htons(port);
          addr1.sin_family      = PF_INET;
          addr1.sin_addr.s_addr = INADDR_ANY;
       
          len = sizeof(addr2);
       
          bind (sock, (SOCKADDR *)&addr1, sizeof(addr1));
       
          listen (sock, 1);
       
           sd = accept (sock, (SOCKADDR *)&addr2, &len);
                       
          if ((sd > 0) && (sd != SCK_EINVALID))
         {
                if (iIndex != SCK_EINVALID)
               {
                         closesocket(iIndex);
              }
                               
              iIndex = sd;                                               
        }


回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117586
QQ
发表于 2018-6-26 11:05:22 | 显示全部楼层
accept后关闭监听端口,closesocket后下次重新创建。这样适用于你所说的修改了端口的情况。
回复

使用道具 举报

3

主题

4

回帖

45

积分

新手上路

积分
45
 楼主| 发表于 2018-6-26 11:13:28 | 显示全部楼层
eric2013,你好:
这种现象是正常的吗? 如果不关闭监听端口,下次有连接过来会自动accept ?

accept后关闭监听端口后,如果客户端掉线了,又要重新打开监听端口,所以想,能不能这个监听端口就一直

开着。。。
回复

使用道具 举报

3

主题

4

回帖

45

积分

新手上路

积分
45
 楼主| 发表于 2018-6-26 11:18:49 | 显示全部楼层
eric2013,你好:

本来是想, 服务端就支持一个活动连接, 有新的连接过来之后,accept,建立新连接,并关闭原来的活动连接。可是发现, 接收数据好像也会触发 accept, 这样会导致另外一个任务里面的receive 一直阻塞。。。。
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117586
QQ
发表于 2018-6-26 11:20:09 | 显示全部楼层
hantech 发表于 2018-6-26 11:13
eric2013,你好:
这种现象是正常的吗? 如果不关闭监听端口,下次有连接过来会自动accept ?

你这种方式的话,参考下面的代码试试

  1. /*********************************************************************
  2. *
  3. *       _ListenAtTcpAddr
  4. *
  5. * Starts listening at the given TCP port.
  6. */
  7. static int _ListenAtTcpAddr(U16 Port) {
  8.   int sock;
  9.   struct sockaddr_in addr = {0};

  10.   sock = socket(AF_INET, SOCK_STREAM, 0);
  11.   memset(&addr, 0, sizeof(addr));
  12.   addr.sin_family      = AF_INET;
  13.   addr.sin_port        = htons(Port);
  14.   addr.sin_addr.s_addr = INADDR_ANY;
  15.   bind(sock, (struct sockaddr *)&addr, sizeof(addr));
  16.   listen(sock, 1);
  17.   return sock;
  18. }

  19. /*********************************************************************
  20. *
  21. *       _ServerTask
  22. *
  23. * Function description
  24. *   This routine is the actual server task.
  25. *   It executes some one-time init code, then runs in an ednless loop.
  26. *   It therefor does not terminate.
  27. *   In the endless loop it
  28. *     - Waits for a conection from a client
  29. *     - Runs the server code
  30. *     - Closes the connection
  31. */
  32. __task void _ServerTask(void) {
  33.   int s, Sock, AddrLen;
  34.   U16 Port;
  35.   //
  36.   // Prepare socket (one time setup)
  37.   //
  38.   Port = 5900 + _Context.ServerIndex; // Default port for VNC is is 590x, where x is the 0-based layer index
  39.   //
  40.   // Loop until we get a socket into listening state
  41.   //
  42.   do {
  43.     s = _ListenAtTcpAddr(Port);
  44.     if (s != -1) {
  45.       break;
  46.     }
  47.     os_dly_wait(100); // Try again
  48.   } while (1);
  49.   //
  50.   // Loop once per client and create a thread for the actual server
  51.   //
  52.   while (1) {
  53.     //
  54.     // Wait for an incoming connection
  55.     //
  56.     AddrLen = sizeof(_Addr);
  57.     if ((Sock = accept(s, (struct sockaddr*)&_Addr, &AddrLen)) < 0) {
  58.       continue; // Error
  59.     }
  60.     //
  61.     // Run the actual server
  62.     //
  63.     GUI_VNC_Process(&_Context, _Send, _Recv, (void *)Sock);
  64.     //
  65.     // Close the connection
  66.     //
  67.     closesocket(Sock);
  68.     memset(&_Addr, 0, sizeof(struct sockaddr_in));
  69.   }
  70. }
复制代码


回复

使用道具 举报

3

主题

4

回帖

45

积分

新手上路

积分
45
 楼主| 发表于 2018-6-26 13:21:11 | 显示全部楼层
eric2013,你好:

如果任务A 里面一直调用 accept 函数的话,会导致 任务B里面的receive阻塞,永远收不到数据; 不调用 accept

的话,又不知道是不是有新的连接请求过来, 有什么好的办法吗 ?
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117586
QQ
发表于 2018-6-26 14:24:46 | 显示全部楼层
hantech 发表于 2018-6-26 13:21
eric2013,你好:

如果任务A 里面一直调用 accept 函数的话,会导致 任务B里面的receive阻塞,永远收不 ...

你多试试,估计是你使用方法的问题。
回复

使用道具 举报

3

主题

4

回帖

45

积分

新手上路

积分
45
 楼主| 发表于 2018-6-27 10:33:37 | 显示全部楼层
eric2013, 你好:

现在是这样的, UCOS系统,一个任务里面,循环调用 accept ;  另外 的任务里面,循环调用 receive,   

断点调试发现, accept,receive 这两个都会用到 互斥信号量,会导致 receive 不正常。。。
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117586
QQ
发表于 2018-6-27 11:36:19 | 显示全部楼层
hantech 发表于 2018-6-27 10:33
eric2013, 你好:

现在是这样的, UCOS系统,一个任务里面,循环调用 accept ;  另外 的任务里面,循环 ...

使用RTX的版本测试,uCOS的版本的多任务做的不够好。
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-8-17 20:49 , Processed in 0.040506 second(s), 24 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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