硬汉嵌入式论坛

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

[RL-TCPnet] 怎么确保RL-TCPnet建立的tcp server只接收一个Client的请求,其他client再连接时提示连接失败

[复制链接]

18

主题

285

回帖

339

积分

高级会员

积分
339
发表于 2018-7-30 11:41:39 | 显示全部楼层 |阅读模式
怎么确保RL-TCPnet建立的tcp server只接收一个Client的请求,即有一个client连接到server后,其他client就无法再连接这个server了,其他client再连接时提示连接失败,这个需要怎么配置呢?

哪位这样操作过,指点一下,谢谢先
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107128
QQ
发表于 2018-7-30 12:13:00 | 显示全部楼层
原始Socket不用配置,TCP就是一对一的。一个服务器对应一个客户端。

如果你用的是BSD Socket,链接后关闭监听就可以了。
回复

使用道具 举报

18

主题

285

回帖

339

积分

高级会员

积分
339
 楼主| 发表于 2018-7-30 21:06:09 | 显示全部楼层
eric2013 发表于 2018-7-30 12:13
原始Skcket不用配置,TCP就是一对一的。一个服务器对应一个客户端。

如果你用的是BSD Socket,链接后关 ...

listen函数的参数中没有关闭监听的参数啊,怎么关闭监听呢
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107128
QQ
发表于 2018-7-31 02:04:43 | 显示全部楼层
看这个帖子里面BSD Socket例子即可

http://www.armbbs.cn/forum.php?m ... &extra=page%3D1
回复

使用道具 举报

29

主题

101

回帖

188

积分

初级会员

积分
188
发表于 2018-7-31 12:05:39 | 显示全部楼层
本帖最后由 captainliuy 于 2018-7-31 12:07 编辑
木兰花 发表于 2018-7-30 21:06
listen函数的参数中没有关闭监听的参数啊,怎么关闭监听呢
关掉listen的sock就行,适当的时候关掉newconn,然后就可以重新listen了
  1.                /* listen for incoming connections (TCP listen backlog = 1) */
  2.                 listen(sock, 1);

  3.                 size = sizeof(remotehost);
  4.                 newconn = accept(sock, (struct sockaddr *)&remotehost, (socklen_t *)&size);
  5.                 close(sock);
复制代码
回复

使用道具 举报

18

主题

285

回帖

339

积分

高级会员

积分
339
 楼主| 发表于 2018-8-1 17:39:37 | 显示全部楼层
本帖最后由 木兰花 于 2018-8-1 18:29 编辑
captainliuy 发表于 2018-7-31 12:05
关掉listen的sock就行,适当的时候关掉newconn,然后就可以重新listen了

测试发现,只需listen(sock, 0);即可实现只连接一个连接的需求,不关闭监听socket可以吗?
回复

使用道具 举报

18

主题

285

回帖

339

积分

高级会员

积分
339
 楼主| 发表于 2018-8-1 17:42:46 | 显示全部楼层
eric2013 发表于 2018-7-31 02:04
看这个帖子里面BSD Socket例子即可

http://www.armbbs.cn/forum.php?mod=viewthread&tid=26034&extra ...

谢谢啦,这个例程写的很好,太感谢啦
  1. void TCPnetTest(void)
  2. {  
  3.         char dbuf[10];
  4.         int len;
  5.         int sock, sd, res;
  6.         SOCKADDR_IN addr;
  7.         SOCKADDR_IN ReAddr;

  8.        
  9.         while (1)
  10.         {
  11.                 /* 创建一个socket
  12.                    第1个参数AF_INET:当前仅支持这个类型的地址族。
  13.                    第2个参数SOCK_STREAM:表示数据流通信类型,即使用的TCP。
  14.                    第3个参数0 :配置为0的话,自动跟第2个参数进行协议匹配,这里就是TCP协议。
  15.                 */
  16.                 sock = socket (AF_INET, SOCK_STREAM, 0);

  17.                 /* 端口号设置为1001 */
  18.                 addr.sin_port        = htons(LocalPort_NUM);
  19.                
  20.                 /* 与函数socket中的AF_INET作用一样 */
  21.                 addr.sin_family      = PF_INET;
  22.                 /*
  23.                    INADDR_ANY就是指定地址为0.0.0.0的地址,这个地址事实上表示不确定地址,或所有地址,
  24.                    任意地址。用在这里的话就表示监控端口号为ddr.sin_port的所有IP地址消息。一般主要用
  25.                    于有多个网卡或者IP地址的情况。开发板只用了DM9161的网口,就是监听这个网口的IP地址。
  26.                 */
  27.                 addr.sin_addr.s_addr = INADDR_ANY;
  28.                
  29.                 /* 给socket绑定IP和端口号 */
  30.                 bind (sock, (SOCKADDR *)&addr, sizeof(addr));

  31.                 /* 设置监听,最大监听1个连接 */
  32.                 listen (sock, 1);
  33.                
  34.                 /*
  35.                    等待soket连接请求,有的话,自动创建1个新的socket进行连接通信,没有的话,等待连接。
  36.                    注意,能够accept的个数受到listen函数的限制,而listen函数又受到Net_Config.c中宏定义
  37.                    BSD_NUMSOCKS 的限制。
  38.                 */
  39.                 len = sizeof(ReAddr);
  40.                 sd = accept (sock, (SOCKADDR *)&ReAddr, &len);
  41.                 printf_debug ("远程客户端请求连接IP: %d.%d.%d.%d\n", ReAddr.sin_addr.s_b1,
  42.                                                              ReAddr.sin_addr.s_b2,
  43.                                                                                                                          ReAddr.sin_addr.s_b3,
  44.                                                              ReAddr.sin_addr.s_b4);
  45.                 printf_debug ("远程客户端端口号: %d\n", ntohs(ReAddr.sin_port));
  46.                
  47.                 /* 关闭监听socket,这个监听socket是调用函数socket后自动创建的 */
  48.                 closesocket (sock);
  49.                 sock = sd;

  50.                
  51.                 while (1)
  52.                 {
  53.                         /*
  54.                           socket数据接收函数,如果recv工作在阻塞模式,使用这个函数注意以下事项:
  55.                           1. 此函数的溢出时间受到Net_Config.c中宏定义 BSD_RCVTOUT 的限制。溢出时间到会自动退出。
  56.                           2. 这个函数接收到一次数据包就会返回,大于或者小于设置的缓冲区大小都没有关系,如果数据量
  57.                              大于接收缓冲区大小,用户只需多次调用函数recv进行接收即可。
  58.                           3. 实际接收到数据大小通过判断此函数的返回值即可。
  59.                         */
  60.                         res = recv (sock, dbuf, sizeof(dbuf), 0);
  61.                         if (res <= 0)
  62.                         {
  63.                                 printf_debug("退出接收函数,重新开始监听%s\r\n", ReVal_Table[abs(res)]);
  64.                                 break;
  65.                         }
  66.                         else
  67.                         {
  68.                                 printf_debug("Receive Data Length = %d\r\n", res);
  69.                                 switch(dbuf[0])
  70.                                 {
  71.                                         /* 字符命令 1 */
  72.                                         case '1':
  73.                                                 sendbuf[0] = '1';
  74.                                                 sendbuf[1] = '2';
  75.                                                 sendbuf[2] = '3';
  76.                                                 sendbuf[3] = '4';
  77.                                                 sendbuf[4] = '5';
  78.                                                 sendbuf[5] = '6';
  79.                                                 sendbuf[6] = '7';
  80.                                                 sendbuf[7] = '8';
  81.                                                 sendbuf[8] = '\r';
  82.                                                 sendbuf[9] = '\n';                                               
  83.                                                 res = send (sock, (char *)sendbuf, 10, 0);
  84.                                                 if (res < 0)
  85.                                                 {
  86.                                                         printf_debug("函数send发送数据失败\r\n");
  87.                                                 }
  88.                                                 else
  89.                                                 {
  90.                                                         printf_debug("函数send发送数据成功\r\n");                                                       
  91.                                                 }
  92.                                                 break;
  93.                                        
  94.                                         /* 字符命令 2 */
  95.                                         case '2':
  96.                                                 /* 将数据缓冲区清成字符0,方便网络调试助手查看数据 */
  97.                                                 len = sizeof(sendbuf);
  98.                                                 memset(sendbuf, 48, len);
  99.                                        
  100.                                                 /* 这里仅初始化了数据包的前4个字节和最后4个字节 */
  101.                                                 sendbuf[0] = 'a';
  102.                                                 sendbuf[1] = 'b';
  103.                                                 sendbuf[2] = 'c';
  104.                                                 sendbuf[3] = 'd';
  105.                                                 sendbuf[len - 4] = 'e';
  106.                                                 sendbuf[len - 3] = 'f';
  107.                                                 sendbuf[len - 2] = 'g';
  108.                                                 sendbuf[len - 1] = 'h';                                       
  109.                                                 res = send (sock, (char *)sendbuf, len, 0);
  110.                                                 if (res < 0)
  111.                                                 {
  112.                                                         printf_debug("函数send发送数据失败%s\r\n", ReVal_Table[abs(res)]);
  113.                                                 }
  114.                                                 else
  115.                                                 {
  116.                                                         printf_debug("函数send成功发送数据 = %d字节\r\n", res);                                                       
  117.                                                 }
  118.                                                 break;
  119.                                
  120.                                         /* 其它数值不做处理 */
  121.                                         default:                     
  122.                                                 break;
  123.                                 }
  124.                         }

  125.                 }
  126.                
  127.                 /*
  128.                    溢出时间到,远程设备断开连接等,程序都会执行到这里,我们在这里关闭socket,
  129.                    程序返回到第一个大while循环的开头重新创建socket并监听。
  130.                 */
  131.                 closesocket (sock);
  132.         }
  133. }
复制代码

回复

使用道具 举报

18

主题

285

回帖

339

积分

高级会员

积分
339
 楼主| 发表于 2018-8-1 18:31:59 | 显示全部楼层
eric2013 发表于 2018-7-31 02:04
看这个帖子里面BSD Socket例子即可

http://www.armbbs.cn/forum.php?mod=viewthread&tid=26034&extra ...

测试发现,只需listen(sock, 0);即可实现只连接一个连接的需求,为什么还有关闭闭监听socket呢?
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107128
QQ
发表于 2018-8-1 18:40:55 | 显示全部楼层
木兰花 发表于 2018-8-1 18:31
测试发现,只需listen(sock, 0);即可实现只连接一个连接的需求,为什么还有关闭闭监听socket呢?

监听本身也要占用1个Socket的,所以要关闭了,无需再占用资源。

配置为0也行吗,这个回头我也测试下。
回复

使用道具 举报

18

主题

285

回帖

339

积分

高级会员

积分
339
 楼主| 发表于 2018-8-2 08:40:53 | 显示全部楼层
eric2013 发表于 2018-8-1 18:40
监听本身也要占用1个Socket的,所以要关闭了,无需再占用资源。

配置为0也行吗,这个回头我也测试下。

哦哦,那我也关闭它吧
配置为0时似乎不太稳定,有时只能连接一个client,有时第二个也能连接成功,但是数据收发不了
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-5-19 22:30 , Processed in 0.174413 second(s), 25 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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