一、连接Wifi热点
主要做法是启动开发板Wifi,然后设置热点和密码等配置信息,再连接热点。
1、先定义两个Wifi监听器,一个连接改变、一个状态改变,并注册监听器。
其中重要的是OnWifiConnectionChanged连接状态事件处理函数。该函数会在连接成功后设置全局变量g_connected=1,代表已经连接成功。
WifiEvent eventListener = { .OnWifiConnectionChanged = OnWifiConnectionChanged, .OnWifiScanStateChanged = OnWifiScanStateChanged }; WifiErrorCode errCode = RegisterWifiEvent(&eventListener); void OnWifiConnectionChanged(int state, WifiLinkedInfo* info) { if (!info) return; if (state == WIFI_STATE_AVALIABLE) { g_connected = 1; } else { g_connected = 0; } }
2、启动Wifi
EnableWifi();
3、设置Wifi热点信息,并返回NetworkId
WifiDeviceConfig apConfig = {}; strcpy(apConfig.ssid, "MyWifi"); strcpy(apConfig.preSharedKey, "12345678"); apConfig.securityType = WIFI_SEC_TYPE_PSK; int netId = -1; AddDeviceConfig(&apConfig, &netId);
4、连接热点,注意此时的g_connected变量,true代表已连接,false代表未连接。
这个状态在事件处理函数中设置。未连接成功时,系统会循环等待,知道事件设置该值。
ConnectTo(netId); while (!g_connected) { osDelay(10); }
二、进行联网,找到wlan0的network interface,然后启动DHCP客户端,获取IP地址。
struct netif* iface = netifapi_netif_find("wlan0"); if (iface) { err_t ret = netifapi_dhcp_start(iface); osDelay(300); }
三、启动TcpSocketServer,并收发消息
1、创建SocketServer,设置服务端口,并启动监听
int sockfd = socket(AF_INET, SOCK_STREAM, 0); struct sockaddr_in serverAddr = {0}; serverAddr.sin_family = AF_INET; serverAddr.sin_port = htons(port); serverAddr.sin_addr.s_addr = htonl(INADDR_ANY); bind(sockfd, (struct sockaddr *)&serverAddr, sizeof(serverAddr)); int backlog = 1; listen(sockfd, backlog)
2、客户端连接。接收客户端消息并发送回去。注意连接后,会创建一个新的Socket File Description。
int connfd = -1; connfd = accept(sockfd, (struct sockaddr *)&clientAddr, &clientAddrLen); recv(connfd, request, sizeof(request), 0); send(connfd, request, strlen(request), 0);
3、关闭TcpSocketServer
lwip_close(connfd); lwip_close(socketfd);
四、联网结束,关闭DHCP客户端,断开Wifi,移除热点的配置信息,禁用Wifi。
err_t ret = netifapi_dhcp_stop(iface); Disconnect(); RemoveDevice(netId); DisableWifi();
五、测试情况如下:
1、启动开发板,连接Wifi热点,启动TcpServer
2、TcpClient(网络调试助手)连接开发板的TcpServer(HiBurn)。
3、TcpClient输入数据并发送,TcpServer接收后再发送回TcpClient。
六、全部源代码,我都注释了,希望大家能够有所参考。
#include #include #include #include #include #include "ohos_init.h" #include "cmsis_os2.h" #include "wifi_device.h" #include "lwip/netifapi.h" #include "lwip/api_shell.h" #include "lwip/sockets.h" // 接收、发送的数据 static char request[128] = ""; // 未连接热点=0,已连接热点=1 static int g_connected = 0; // 输出连接信息字符串 // 打印内容样例--> bssid: 38:47:BC:49:01:FA, rssi: 0, connState: 0, reason: 0, ssid: MyMobile void PrintLinkedInfo(WifiLinkedInfo* info) { if (!info) return; static char macAddress[32] = {0}; unsigned char* mac = info->bssid; snprintf(macAddress, sizeof(macAddress), "%02X:%02X:%02X:%02X:%02X:%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); printf("bssid: %s, rssi: %d, connState: %d, reason: %d, ssid: %srn", macAddress, info->rssi, info->connState, info->disconnectedReason, info->ssid); } // 连接状态改变事件处理 void OnWifiConnectionChanged(int state, WifiLinkedInfo* info) { if (!info) return; // 输出类似内容:OnWifiConnectionChanged 31, state = 1, info = printf("%s %d, state = %d, info = rn", __FUNCTION__, __LINE__, state); PrintLinkedInfo(info); // 根据连接状态设置g_connected if (state == WIFI_STATE_AVALIABLE) { g_connected = 1; } else { g_connected = 0; } } // 扫描状态改变事件处理 void OnWifiScanStateChanged(int state, int size) { printf("%s %d, state = %X, size = %drn", __FUNCTION__, __LINE__, state, size); } void DisconnectTcpSocket(int connfd) { sleep(1); printf("do_disconnect...rn"); lwip_close(connfd); sleep(1); // for debug } void CloseTcpSocket(int socketfd) { printf("do_cleanup...rn"); lwip_close(socketfd); } static void TcpServerHandler(void) { ssize_t retval = 0; unsigned short port = 9118; // 创建一个通信的Socket,并返回一个Socket文件描述符。第一个参数IpV4,第二个参数SOCK_STREAM类型,第三个指用到的协议 int sockfd = socket(AF_INET, SOCK_STREAM, 0); // 客户端地址和地址长度 struct sockaddr_in clientAddr = {0}; socklen_t clientAddrLen = sizeof(clientAddr); // 服务端地址 struct sockaddr_in serverAddr = {0}; serverAddr.sin_family = AF_INET; // htons是将整型变量从主机字节顺序转变成网络字节顺序,就是整数在地址空间存储方式变为高位字节存放在内存的低地址处 serverAddr.sin_port = htons(port); // 监听本机的所有IP地址,INADDR_ANY=0x0 // 将主机数转换成无符号长整型的网络字节顺序 serverAddr.sin_addr.s_addr = htonl(INADDR_ANY); // 服务端绑定端口 retval = bind(sockfd, (struct sockaddr *)&serverAddr, sizeof(serverAddr)); if (retval关注打赏
最近更新
- 深拷贝和浅拷贝的区别(重点)
- 【Vue】走进Vue框架世界
- 【云服务器】项目部署—搭建网站—vue电商后台管理系统
- 【React介绍】 一文带你深入React
- 【React】React组件实例的三大属性之state,props,refs(你学废了吗)
- 【脚手架VueCLI】从零开始,创建一个VUE项目
- 【React】深入理解React组件生命周期----图文详解(含代码)
- 【React】DOM的Diffing算法是什么?以及DOM中key的作用----经典面试题
- 【React】1_使用React脚手架创建项目步骤--------详解(含项目结构说明)
- 【React】2_如何使用react脚手架写一个简单的页面?