Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
RT-Thread一般讨论
Rtt中TCP服务器怎么实现多个客户端的链接处理?
发布于 2013-07-17 15:26:22 浏览:4985
订阅该版
Rtt版本1.1.0 ;平台 STM32107;程序bsp中的107工程文件。 实验目的:将STM32作为TCP服务端,接收多个客户端的链接并进行处理。 实验方法:直接将网站中“TCP/IP网络组件Lwip 之 TCP Server”的“tcpserv();”作为函数添加到“rt_init_thread_entry”线程中。 实验结果:将客户端A连接到服务器后,进行数据通信;此时再将客户端B连接到服务器上时,无法进行数据的通信,必须等A连接断开后才能进行通信。 尝试处理手段:每次A与服务器通信后都断开连接。下次通信再进行连接,此法会消耗内存,直到消耗完毕。 问题:应该怎么利用套接字(或别的方式)进行编程让AB客户端能与服务器进行独立的通讯。 是否有相应的代码可以提供进行参考。 谢谢。 ![1.jpg](https://oss-club.rt-thread.org/uploads/5314_1c75a06184f4df0867cb9f976a57578d.jpg)
查看更多
11
个回答
默认排序
按发布时间排序
bernard
2013-07-17
这家伙很懒,什么也没写!
有两种方法: 1. 创建出一个新的任务来处理新的连接; 2. 使用select。
celticzy
2013-07-17
这家伙很懒,什么也没写!
>有两种方法: >1. 创建出一个新的任务来处理新的连接; >2. 使用select。 --- 第一种方法的代码,我之前写了一个,还请高手帮忙看看有什么漏洞没有。(PS,select是啥?) ``` ALIGN(RT_ALIGN_SIZE) static rt_uint8_t tcp_server_stack[ 1024 ]; static struct rt_thread tcp_server_thread; //echo 服务线程 static void server_echo(void* para) { struct netbuf *buf; rt_uint8_t *rec_data; rt_uint16_t rec_data_len; while(1) { netconn_recv(para,&buf); if(buf != NULL) { netbuf_data(buf,(void**)&rec_data,&rec_data_len); netconn_write(para,rec_data,rec_data_len,NETCONN_COPY); netbuf_delete(buf); } else { //关闭连接,回收资源 rt_kprintf("sever close! "); netconn_delete(para); break; } } } //监听56793端口线程,有新的连接进来则转至echo线程处理 static void tcp_server_thread_entry(void* parameter) { const rt_uint8_t welcome[] = "hello, world! "; struct netconn *receive_conn, *new_conn; rt_thread_t tid = RT_NULL; new_conn = netconn_new(NETCONN_TCP); netconn_bind(new_conn,NULL,56793); netconn_listen(new_conn); while(1) { netconn_accept(new_conn,&receive_conn); //向新的连接发送欢迎信息 netconn_write(receive_conn,welcome,sizeof(welcome),NETCONN_COPY); rt_kprintf("sever open! "); tid = rt_thread_create("connect",server_echo,(void*)receive_conn,1024,20,5); if(tid != RT_NULL) { rt_thread_startup(tid); } else { rt_kprintf("creat echo server failed. "); break; } } netconn_delete(new_conn); } //对外的初始化接口 int tcp_server_thread_init(void) { rt_err_t result; result = rt_thread_init(&tcp_server_thread, "tcp_ser", tcp_server_thread_entry, RT_NULL, (rt_uint8_t*)&tcp_server_stack[0], sizeof(tcp_server_stack), 20, 5); if (result == RT_EOK) { rt_thread_startup(&tcp_server_thread); } return 0; } ``` 实测结果如下: [attach]1914[/attach] 另外,打开3个连接后与关闭它们后,一些系统状态如下: ``` sever open! sever open! sever open! finsh>>list_thre --function: list_thread -- list thread finsh>>list_thread() thread pri status sp stack size max used left tick error -------- ---- ------- ---------- ---------- ---------- ---------- --- connect 0x14 suspend 0x000001a8 0x00000400 0x000001b8 0x00000005 000 connect 0x14 suspend 0x000001a8 0x00000400 0x000001b8 0x00000005 000 connect 0x14 suspend 0x000001a8 0x00000400 0x000001b8 0x00000005 000 telnet 0x19 suspend 0x00000168 0x00000800 0x00000190 0x00000001 000 tcp_ser 0x14 suspend 0x00000180 0x00000400 0x000001b0 0x00000002 000 tcpip 0x0c suspend 0x00000160 0x00000400 0x00000270 0x0000000b 000 etx 0x0f suspend 0x0000011c 0x00000200 0x0000011c 0x00000010 000 erx 0x0f suspend 0x0000011c 0x00000200 0x0000018c 0x0000000d 000 tshell 0x14 ready 0x00000240 0x00000800 0x00000240 0x0000000a -04 phy 0x1e suspend 0x00000118 0x00000200 0x00000150 0x00000001 000 tidle 0x1f ready 0x000000e0 0x00000400 0x000000e0 0x00000008 000 timer 0x04 suspend 0x000000e0 0x00000200 0x000000e0 0x00000009 000 0, 0x00000000 finsh>>list_mem() total memory: 2097112 used memory : 15224 maximum allocated memory: 15520 0, 0x00000000 finsh>>list_tcps() Active PCB states: #0 10.30.28.35:56793 <==> 10.30.28.100:56961 snd_nxt 0x000019CB rcv_nxt 0x97571EFB state: ESTABLISHED #1 10.30.28.35:56793 <==> 10.30.28.100:56960 snd_nxt 0x000019A3 rcv_nxt 0x59B407E6 state: ESTABLISHED #2 10.30.28.35:56793 <==> 10.30.28.100:56958 snd_nxt 0x00001986 rcv_nxt 0xF4FC9CAA state: ESTABLISHED Listen PCB states: #0 local port 56793 state: LISTEN #1 local port 23 state: LISTEN TIME-WAIT PCB states: 0, 0x00000000 finsh>>sever close! sever close! sever close! finsh>>list_thread() thread pri status sp stack size max used left tick error -------- ---- ------- ---------- ---------- ---------- ---------- --- telnet 0x19 suspend 0x00000168 0x00000800 0x00000190 0x00000001 000 tcp_ser 0x14 suspend 0x00000180 0x00000400 0x000001b0 0x00000002 000 tcpip 0x0c suspend 0x00000160 0x00000400 0x00000270 0x00000006 000 etx 0x0f suspend 0x0000011c 0x00000200 0x0000011c 0x00000010 000 erx 0x0f suspend 0x0000011c 0x00000200 0x0000018c 0x0000000c 000 tshell 0x14 ready 0x00000110 0x00000800 0x00000240 0x00000009 -04 phy 0x1e suspend 0x00000118 0x00000200 0x00000150 0x00000001 000 tidle 0x1f ready 0x000000e0 0x00000400 0x000000e0 0x0000000a 000 timer 0x04 suspend 0x000000e0 0x00000200 0x000000e0 0x00000009 000 0, 0x00000000 finsh>>list_mem() total memory: 2097112 used memory : 10264 maximum allocated memory: 15576 0, 0x00000000 finsh>> finsh>>list_tcps() Active PCB states: Listen PCB states: #0 local port 56793 state: LISTEN #1 local port 23 state: LISTEN TIME-WAIT PCB states: 0, 0x00000000 finsh>> ```
nongxiaoming
2013-07-17
rt-thread大师兄
select是lwip里面的一种非阻塞处理机制,使用select可以设定超时时间。使用select可以在同一个线程里面处理多个socket消息。
celticzy
2013-07-17
这家伙很懒,什么也没写!
>select是lwip里面的一种非阻塞处理机制,使用select可以设定超时时间。使用select可以在同一个线程里面处理多个socket消息。 --- 现在lwip1.41版本的socket方式编程稳定吗?以前官方的手册都不是特别推荐,那一章就忽略没学了。。。
bernard
2013-07-17
这家伙很懒,什么也没写!
创建线程处理的方式,问题在于:当网络上持续不断的发起连接时,如果不正确设置连接数,将把系统的内存消耗光。
lyq262
2013-07-18
这家伙很懒,什么也没写!
首先感谢楼上的各位回复。 正题: 用第一种建立线程的方式做了实验,可以处理多客户端的链接。 程序代码在原来的tcpserv()中 ``` connected = accept(sock, (struct sockaddr *)&client_addr, &sin_size); ``` 替换成下面代码,并注释掉while(1)的内容 ``` connected[index] = accept(sock, (struct sockaddr *)&client_addr, &sin_size); if(connected[index]!=-1) tid = rt_thread_create("connect",server_echo,(void*)&connected[index++],1024,20,5); ``` ``` void server_echo(int* parameter) { int str=0,bytes_received; char *recv_data1; recv_data1 = rt_malloc(1024); while (1) { /* 浠庨偖绠变腑鏀跺彇閭?欢 */ rt_kprintf("socket:%d ",*parameter); send(*parameter, send_data, strlen(send_data), 0); bytes_received = recv(*parameter, recv_data1, 1024, 0); if (bytes_received <= 0) { /* 接收失败,关闭这个connected socket */ lwip_close(*parameter); rt_free(recv_data1); break; } recv_data1[bytes_received] = ' '; /* 寤舵椂10涓狾S Tick */ rt_kprintf("RECIEVED 123 = %s " , recv_data1); } } ``` 新状况出现了:当第六个TCP链接来时出现以下状况(串口的输出信息) TCPServer Waiting for client on port 5000... socket:1 socket:2 socket:3 socket:4 socket:5 (thread->stat == RT_THREAD_INIT) assert failed at rt_thread_startup:198。 在代码中不加if的话输出信息:socket:-1。 Active PCB states: 192.168.1.141:5000 <==> 192.168.1.141:53672 snd_nxt 6656 rcv_nxt -1379197972 sta te: ESTABLISHED 192.168.1.141:5000 <==> 192.168.1.141:53669 snd_nxt 6605 rcv_nxt -942710139 stat e: ESTABLISHED 192.168.1.141:5000 <==> 192.168.1.141:53668 snd_nxt 6561 rcv_nxt -289775766 stat e: ESTABLISHED 192.168.1.141:5000 <==> 192.168.1.141:53667 snd_nxt 6550 rcv_nxt 824871278 state : ESTABLISHED 192.168.1.141:5000 <==> 192.168.1.141:52262 snd_nxt 6545 rcv_nxt -1175041001 sta te: ESTABLISHED Listen PCB states: local port 5000 state: LISTEN TIME-WAIT PCB states: 0, 0x00000000 finsh>>list_mem() total memory: 44336 used memory : 19160 maximum allocated memory: 19856 32, 0x00000020 finsh>> 配置信息:在原工程的配置上只修改了 #define RT_LWIP_TCP_PCB_NUM 20(TCP链接控制参数? 但是没效果,我改成3,也能链接5个TCP) 问题:1 该情况出现的原因?和解决办法?(系统内存够用,难道是线程数量受限?线程空间不够?) 2.TCP链接数的控制。有配置参数? 3.192.168.1.141:5000 <==> 192.168.1.141:52262 (IP一样??)
celticzy
2013-07-18
这家伙很懒,什么也没写!
>配置信息:在原工程的配置上只修改了 >#define RT_LWIP_TCP_PCB_NUM 20(TCP链接控制参数? 但是没效果,我改成3,也能链接5个TCP) >问题:1 该情况出现的原因?和解决办法?(系统内存够用,难道是线程数量受限?线程空间不够?) >2.TCP链接数的控制。有配置参数? >3.192.168.1.141:5000 <==> 192.168.1.141:52262 (IP一样??) --- 我也很奇怪呢。。。 1、2、我的也是,同问 3、不奇怪,5000端口把已建立的连接转移到本地其它端口了, 不过,我不明白为什么你这儿显示的是本地IP+端口,而我显示的是对方IP+端口。 我的平台:stm32f407+rt-thread 1.20 + lwip 1.40。这是老早以前在github上弄的一个组合。 加一条,兄弟能不能把你用socket方式写的代码发几份给我学习一下?我不会这种方式的lwip编程,但看到好多人都在用。
aozima
2013-07-18
调网络不抓包,调I2C等时序不上逻辑分析仪,就像电工不用万用表!多用整理的好的文字,比截图更省流量,还能在整理过程中思考。
>3.192.168.1.141:5000 <==> 192.168.1.141:52262 (IP一样??) --- 这个问题已经修正过了,请使用新的代码:[https://github.com/RT-Thread/rt-thread/pull/41](fixed list_tcps bug: ipaddr_ntoa isn't reentrant.)
lyq262
2013-07-18
这家伙很懒,什么也没写!
>我也很奇怪呢。。。 > >1、2、我的也是,同问 >3、不奇怪,5000端口把已建立的连接转移到本地其它端口了, > 不过,我不明白为什么你这儿显示的是本地IP+端口,而我显示的是对方IP+端口。 > > 我的平台:stm32f407+rt-thread 1.20 + lwip 1.40。这是老早以前在github上弄的一个组合。 > >加一条,兄弟能不能把你用socket方式写的代码发几份给我学习一下?我不会这种方式的lwip编程,但看到好多人都在用。 --- 这是我第一次用套接字。也就这个例程了
lyq262
2013-07-18
这家伙很懒,什么也没写!
>>3.192.168.1.141:5000 <==> 192.168.1.141:52262 (IP一样??) > >--- > > >这个问题已经修正过了,请使用新的代码:[https://github.com/RT-Thread/rt-thread/pull/41](fixed list_tcps bug: ipaddr_ntoa isn't reentrant.) --- 版主关于另两个问题有解答的吗? 或者提示的方向
撰写答案
登录
注册新账号
关注者
0
被浏览
5k
关于作者
lyq262
这家伙很懒,什么也没写!
提问
1
回答
3
被采纳
0
关注TA
发私信
相关问题
1
有关动态模块加载的一篇论文
2
最近的调程序总结
3
晕掉了,这么久都不见layer2的踪影啊
4
继续K9ii的历程
5
[GUI相关] FreeType 2
6
[GUI相关]嵌入式系统中文输入法的设计
7
20081101 RT-Thread开发者聚会总结
8
嵌入式系统基础
9
linux2.4.19在at91rm9200 上的寄存器设置
10
[转]基于嵌入式Linux的通用触摸屏校准程序
推荐文章
1
RT-Thread应用项目汇总
2
玩转RT-Thread系列教程
3
国产MCU移植系列教程汇总,欢迎查看!
4
机器人操作系统 (ROS2) 和 RT-Thread 通信
5
五分钟玩转RT-Thread新社区
6
【技术三千问】之《玩转ART-Pi》,看这篇就够了!干货汇总
7
关于STM32H7开发板上使用SDIO接口驱动SD卡挂载文件系统的问题总结
8
STM32的“GPU”——DMA2D实例详解
9
RT-Thread隐藏的宝藏之completion
10
【ART-PI】RT-Thread 开启RTC 与 Alarm组件
最新文章
1
【NXP-MCXA153】 定时器驱动移植
2
GD32F450 看门狗驱动适配
3
【NXP-MCXA153】看门狗驱动移植
4
RT-Thread Studio V2.2.9 Release Note
5
CherryUSB的bootuf2配置
热门标签
RT-Thread Studio
串口
Env
LWIP
SPI
AT
Bootloader
Hardfault
CAN总线
FinSH
ART-Pi
USB
DMA
文件系统
RT-Thread
SCons
RT-Thread Nano
线程
MQTT
STM32
RTC
FAL
rt-smart
ESP8266
I2C_IIC
UART
WIZnet_W5500
ota在线升级
PWM
freemodbus
flash
cubemx
packages_软件包
BSP
潘多拉开发板_Pandora
定时器
ADC
GD32
flashDB
socket
中断
编译报错
Debug
rt_mq_消息队列_msg_queue
SFUD
keil_MDK
msh
ulog
C++_cpp
MicroPython
本月问答贡献
踩姑娘的小蘑菇
7
个答案
2
次被采纳
a1012112796
18
个答案
1
次被采纳
Ryan_CW
5
个答案
1
次被采纳
红枫
4
个答案
1
次被采纳
张世争
4
个答案
1
次被采纳
本月文章贡献
YZRD
3
篇文章
6
次点赞
catcatbing
3
篇文章
6
次点赞
lizimu
2
篇文章
9
次点赞
qq1078249029
2
篇文章
2
次点赞
xnosky
2
篇文章
1
次点赞
回到
顶部
发布
问题
分享
好友
手机
浏览
扫码手机浏览
投诉
建议
回到
底部