
WIFI模块开发教程之W600网络篇2:AP模式下TCP Server通信
每次accept到客户端连接后,会创建一个新的线程处理数据交互,本demo支持一个模块同时支持多个TCP客户端通信。 设备调试串口信息中可能出现
发布日期:2021-05-15 00:02:28
浏览次数:20
分类:精选文章
本文共 5157 字,大约阅读时间需要 17 分钟。
在AP模式下实现TCP Server通信
前言
本文旨在探讨如何在AP模式下进行TCP Server通信。在AP模式下,模块可以作为一个softAP热点提供服务,当其他设备连接成功后,模块作为服务端等待客户端连接并进行通信。
理论基础
本节主要处理两个问题:如何利用RT_Thread连接路由器,以及如何使用Socket套接字编程实现TCP Server程序。
1. 连接路由器
模块需要开启station模式并连接到路由器。RT_Thread中,只需调用rt_wlan_set_mode
和rt_wlan_start_ap
函数即可实现。
rt_wlan_set_mode(RT_WLAN_DEVICE_AP_NAME, RT_WLAN_AP);rt_wlan_start_ap("sand", "12345678");
2. Socket套接字实现TCP Server
服务端套接字使用流程以及和客户端交互框图如下所示(图片描述见附件)。
使用实例
1. 程序
程序位于w60x/applications/4-ap_tcp_server/main.c
。以下是代码片段:
#include#include #include #define TCP_SERVER_ADDR "192.168.169.1"#define TCP_SERVER_PORT 8089static void tcp_client_thread_entry(void *args) { int ret = 0; int fd = (int) args; int len = 0; fd_set readfds; char buf[512] = {0}; struct timeval t; t.tv_sec = 5; t.tv_usec = 0; while (1) { FD_ZERO(&readfds); FD_SET(fd, &readfds); ret = select(fd + 1, &readfds, NULL, NULL, &t); if ((ret > 0) && FD_ISSET(fd, &readfds)) { len = recv(fd, buf, sizeof(buf), 0); if (len > 0) { buf[len] = 0x00; rt_kprintf("receive data:%s\r\n", buf); } else { rt_kprintf("receive data from tcp server error!\r\n"); goto exit; } if (-1 != fd) { rt_sprintf(buf, "%s\r\n", buf); ret = send(fd, buf, strlen(buf), 0); if (ret < 0) { rt_kprintf("send error, close socket"); goto exit; } } } }exit: if (-1 != fd) { closesocket(&fd); fd = -1; }}static void tcp_server_thread_entry(void *args) { int ret = 0; int fd = -1, client_fd = -1; struct sockaddr_in server_addr, client_addr; struct timeval t; fd_set readfds; socklen_t sockaddr_t_size; char buf[512] = {0}; int len = 0;reconnect: fd = socket(AF_INET, SOCK_STREAM, 0); if (-1 == fd) { rt_kprintf("create socket error!!!\r\n"); goto exit; } server_addr.sin_family = AF_INET; server_addr.sin_port = htons(TCP_SERVER_PORT); server_addr.sin_addr.s_addr = INADDR_ANY; rt_memset(&server_addr.sin_zero, 0x00, sizeof(server_addr.sin_zero)); ret = bind(fd, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)); if (0 == ret) { rt_kprintf("bind success\r\n"); } else { rt_kprintf("connect error!!!\r\n"); goto try_reconnect; } ret = listen(fd, 5); if (-1 == ret) { rt_kprintf("Listen error\r\n"); goto try_reconnect; } t.tv_sec = 2; t.tv_usec = 0; while (1) { FD_ZERO(&readfds); FD_SET(fd, &readfds); ret = select(fd + 1, &readfds, 0, 0, &t); if (-1 == ret) { rt_kprintf("select() error!\r\n"); goto try_reconnect; } else if (ret > 0) { if (FD_ISSET(fd, &readfds)) { client_fd = accept(fd, (struct sockaddr *)&client_addr, &sockaddr_t_size); if (client_fd < 0) { rt_kprintf("accept connection failed! errno = %d\n", errno); continue; } rt_kprintf("client connected, ip:%s, port:%d", inet_ntoa(client_addr), ntohs(client_addr.sin_port)); //create client thread rt_thread_t uart_thread = rt_thread_create("clients", tcp_client_thread_entry, client_fd, 4*1024, 25, 10); if (uart_thread != NULL) { rt_thread_startup(uart_thread); } else { ret = RT_ERROR; rt_kprintf("create tcp client error!!!"); closesocket(fd); } } } }try_reconnect: if (-1 != fd) { closesocket(fd); } rt_thread_sleep(1); goto reconnect;exit: if (-1 != fd) { closesocket(fd); } rt_kprintf("thread server exit!\r\n");}int main(void) { rt_err_t ret = RT_EOK; char str[] = "hello world!\r\n"; rt_wlan_set_mode(RT_WLAN_DEVICE_AP_NAME, RT_WLAN_AP); rt_wlan_start_ap("sand", "12345678"); rt_thread_t uart_thread = rt_thread_create("server", tcp_server_thread_entry, RT_NULL, 4*1024, 25, 10); if (uart_thread != NULL) { rt_thread_startup(uart_thread); } else { ret = RT_ERROR; rt_kprintf("create tcp client error!!!"); }exit: return ret;}
2. 目标文件配置
默认的SConscript
脚本需要修改以支持4-ap_tcp_server
项目。修改后的脚本如下:
Import('RTT_ROOT')Import('rtconfig')from building import *cwd = GetCurrentDir()src = Glob('4-ap_tcp_server/main.c')CPPPATH = [cwd]group = DefineGroup('Applications', src, depend=[''], CPPPATH = CPPPATH)Return('group')
下载运行
在ENV控制台中,输入scons
命令生成build/Bin/rtthread_1M.FLS
文件。烧录运行后,连接模块的热点,使用网络助手配置两个TCP客户端,设置目标IP和端口为192.168.169.1:8089
。通过发送数据测试通信功能。
结语
总结
实际操作中需注意以下几点:
receive data from tcp server error!
,这可能是由于手动关闭客户端导致,正常情况下模块日志检测到客户端连接。资料获取
如有疑问,可加入QQ交流群906015840
(备注:物联网项目交流),或关注公众号“物联网客栈”(扫码关注)。
发表评论
最新留言
初次前来,多多关照!
[***.217.46.12]2025年05月04日 04时40分55秒
关于作者

喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
Grafana导入 Promethus node模板
2019-03-12
如何提高SQL查询的效率?
2019-03-12
Docker入门之-镜像(二)
2019-03-12
数据结构——链表(3)
2019-03-12
socket模块和粘包现象
2019-03-12
Python学习--模块
2019-03-12
去了解拉绳位移编码器的影响因素
2019-03-12
影响拉线位移传感器精度的原因有哪些?
2019-03-12
无法初始化Winsock2.2处理
2019-03-12
Horizon Cloud之UAG访问异常
2019-03-12
vm无法打开电源
2019-03-12
vMotion 操作失败进度卡在14% ,报错: Operation Timed out
2019-03-12
重置UAG Application admin密码
2019-03-12
Horizon Daas租户管理平台扩展分配时报:内部错误
2019-03-12
vcenter访问报503错误处理
2019-03-12
项目计划甘特图绘制说明
2019-03-12
09.QT应用程序启动外部exe文件
2019-03-12
1009. clion调试段错误
2019-03-12
C/C++:线性表之顺序表
2019-03-12
嵌入式系统试题库(CSU)
2019-03-12