WIFI模块开发教程之W600网络篇2:AP模式下TCP Server通信
发布日期: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_modert_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 8089
static 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。通过发送数据测试通信功能。

结语

总结

实际操作中需注意以下几点:

  • 每次accept到客户端连接后,会创建一个新的线程处理数据交互,本demo支持一个模块同时支持多个TCP客户端通信。
  • 设备调试串口信息中可能出现receive data from tcp server error!,这可能是由于手动关闭客户端导致,正常情况下模块日志检测到客户端连接。
  • 资料获取

    如有疑问,可加入QQ交流群906015840(备注:物联网项目交流),或关注公众号“物联网客栈”(扫码关注)。

    上一篇:WIFI模块开发教程之W600网络篇3:STA模式下TCP Client通信
    下一篇:WIFI模块开发教程之W600网络篇1:AP模式下TCP Client通信

    发表评论

    最新留言

    初次前来,多多关照!
    [***.217.46.12]2025年05月04日 04时40分55秒