您当前的位置: 首页 > 

Linux小百科

暂无认证

  • 0浏览

    0关注

    1185博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

如何使用鸿蒙Hi3861来完成Wifi热点的连接,并启动TCP SocketServer?

Linux小百科 发布时间:2021-02-22 09:41:36 ,浏览量:0

这次使用Hi3861来完成Wifi热点的连接,并启动TCP SocketServer,接收消息并将消息反馈TcpCLient。

一、连接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

如何使用鸿蒙Hi3861来完成Wifi热点的连接,并启动TCP SocketServer?如何使用鸿蒙Hi3861来完成Wifi热点的连接,并启动TCP SocketServer?

2、TcpClient(网络调试助手)连接开发板的TcpServer(HiBurn)。

如何使用鸿蒙Hi3861来完成Wifi热点的连接,并启动TCP SocketServer?如何使用鸿蒙Hi3861来完成Wifi热点的连接,并启动TCP SocketServer?如何使用鸿蒙Hi3861来完成Wifi热点的连接,并启动TCP SocketServer?如何使用鸿蒙Hi3861来完成Wifi热点的连接,并启动TCP SocketServer?

3、TcpClient输入数据并发送,TcpServer接收后再发送回TcpClient。

如何使用鸿蒙Hi3861来完成Wifi热点的连接,并启动TCP SocketServer?如何使用鸿蒙Hi3861来完成Wifi热点的连接,并启动TCP SocketServer?如何使用鸿蒙Hi3861来完成Wifi热点的连接,并启动TCP SocketServer?如何使用鸿蒙Hi3861来完成Wifi热点的连接,并启动TCP SocketServer?

六、全部源代码,我都注释了,希望大家能够有所参考。

#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             
关注
打赏
1665632672
查看更多评论
立即登录/注册

微信扫码登录

0.0418s