赞
踩
参考网上连老师的TCP自己整理一套TCP服务端的开发,整体思路大概如下:
1、TCP服务首先需要连接WiFi,采用的是STA模式,在编写TCP服务端代码之前已经对WiFi功能进行了学习,代码也编写好了,所以直接封装一下拿来使用就OK!!代码如下,在applications/sample/wifi-iot/app/下新建wifi_demo文件夹,然后新建wifi_sta_connect.h文件和wifi_sta_connect.c文件:
wifi_sta_connect.h
#ifndef _WIFI_STA_CONNECT_H
#define _WIFI_STA_CONNECT_H
extern int g_connected;
//WIFI sta模式相关功能函数
void PrintLinkedInfo(WifiLinkedInfo* info);
void OnWifiConnectionChanged(int state, WifiLinkedInfo* info);
void OnWifiScanStateChanged(int state, int size);
#endif
wifi_sta_connect.c
#include <stdio.h> #include <string.h> #include <unistd.h> #include "ohos_init.h" #include "cmsis_os2.h" #include "wifi_device.h" #include "lwip/netifapi.h" #include "lwip/api_shell.h" #include "wifi_sta_connect.h" 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: %s\r\n", macAddress, info->rssi, info->connState, info->disconnectedReason, info->ssid); } int g_connected = 0; void OnWifiConnectionChanged(int state, WifiLinkedInfo* info) { if (!info) return; printf("%s %d, state = %d, info = \r\n", __FUNCTION__, __LINE__, state); PrintLinkedInfo(info); if (state == WIFI_STATE_AVALIABLE) { g_connected = 1; } else { g_connected = 0; } } void OnWifiScanStateChanged(int state, int size) { printf("%s %d, state = %X, size = %d\r\n", __FUNCTION__, __LINE__, state, size); }
2、WiFi功能模块封装的相对简单,后期如果需要更多的功能,在模块中添加即可,接下来就是TCP服务端代码的编写,其中需要调用WiFi功能。
在applications/sample/wifi-iot/app下新建socket_demo文件夹,然后添加tcp_server_test.c文件
tcp_server_test.c
#include <stdio.h> #include <unistd.h> #include "ohos_init.h" #include "cmsis_os2.h" #include "wifi_device.h" #include "lwip/api_shell.h" #include "hi_wifi_api.h" #include "lwip/ip_addr.h" #include "lwip/netifapi.h" #include "lwip/sockets.h" #include "wifi_sta_connect.h" #define SERVER_PORT_TCP 6666 #define TCP_BACKLOG 10 /* 在sock_fd 进行监听,在 new_fd 接收新的链接 */ int sock_fd, new_fd; char recvbuf[512]; char *buf = "hello! I'm server!"; int tcp_server_demo(void){ /* 自己的地址信息 */ struct sockaddr_in my_addr; /* 连接者的地址信息*/ struct sockaddr_in their_addr; int sin_size; struct sockaddr_in *cli_addr; printf("%s %d \r\n", __FILE__, __LINE__); /* 1 、创建socket */ if((sock_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { printf("%s %d \r\n", __FILE__, __LINE__); perror("socket is error\r\n"); exit(1); } /* 主机字节顺序 */ /* 协议 */ my_addr.sin_family = AF_INET; my_addr.sin_port = htons(6666);//设置你的端口号 /* 当前IP 地址写入 */ my_addr.sin_addr.s_addr = INADDR_ANY; /* 将结构体其余的都清零 */ bzero(&(my_addr.sin_zero), 8); printf("%s %d \r\n", __FILE__, __LINE__); /* bind 绑定*/ if(bind(sock_fd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)) == -1) { printf("%s %d \r\n", __FILE__, __LINE__); perror("bind is error\r\n"); exit(1); } printf("%s %d \r\n", __FILE__, __LINE__); /* 开始监听 */ if(listen(sock_fd, TCP_BACKLOG) == -1) { perror("listen is error\r\n"); exit(1); } printf("%s %d \r\n", __FILE__, __LINE__); printf("start accept\n"); /* accept() 循环 */ while(1) { sin_size = sizeof(struct sockaddr_in); printf("%s %d \r\n", __FILE__, __LINE__); if((new_fd = accept(sock_fd, (struct sockaddr *)&their_addr, (socklen_t *)&sin_size)) == -1) { perror("accept"); continue; } cli_addr = malloc(sizeof(struct sockaddr)); printf("accept addr\r\n"); if(cli_addr != NULL) { memcpy(cli_addr, &their_addr, sizeof(struct sockaddr)); } //处理目标 ssize_t ret; while(1) { printf("%s %d \r\n", __FILE__, __LINE__); if((ret = recv(new_fd, recvbuf, sizeof(recvbuf), 0)) == -1){ printf("recv error \r\n"); return -1; } printf("recv :\r\n"); printf("%s", recvbuf); printf("\r\n"); sleep(2); if((ret = send(new_fd, buf, strlen(buf) + 1, 0)) == -1) { perror("send : "); } sleep(2); } close(new_fd); return 0; } } void start_sta_mode(void){ WifiErrorCode errCode; WifiEvent eventListener = { .OnWifiConnectionChanged = OnWifiConnectionChanged, //连接状态改变 .OnWifiScanStateChanged = OnWifiScanStateChanged //扫描状态变化 }; WifiDeviceConfig apConfig = {}; int netId = -1; osDelay(10); errCode = RegisterWifiEvent(&eventListener); //注册wifi事件的回调函数 printf("RegisterWifiEvent: %d\r\n", errCode); // setup your AP params strcpy(apConfig.ssid, "*******"); //设置你的wifi名称 strcpy(apConfig.preSharedKey, "*******"); //设置你的wifi密码 apConfig.securityType = WIFI_SEC_TYPE_PSK; while (1) { errCode = EnableWifi(); //打开wifi设备的sta模式,使其可以扫描 printf("EnableWifi: %d\r\n", errCode); osDelay(10); errCode = AddDeviceConfig(&apConfig, &netId); //增加WIFI设备的配置,分配得到一个net id保存在netId中 printf("AddDeviceConfig: %d\r\n", errCode); g_connected = 0; errCode = ConnectTo(netId); printf("ConnectTo(%d): %d\r\n", netId, errCode); while (!g_connected) { osDelay(10); } printf("g_connected: %d\r\n", g_connected); osDelay(50); // 联网业务开始 struct netif* iface = netifapi_netif_find("wlan0"); if (iface) { err_t ret = netifapi_dhcp_start(iface); printf("netifapi_dhcp_start: %d\r\n", ret); osDelay(200); // wait DHCP server give me IP ret = netifapi_netif_common(iface, dhcp_clients_info_show, NULL); printf("netifapi_netif_common: %d\r\n", ret); } // 模拟一段时间的联网业务 // int timeout = 60; while (1) { // osDelay(100); // printf("after %d seconds, I'll disconnect WiFi!\n", timeout); printf("ongoing Iot business\n"); uint32_t result = tcp_server_demo(); if (result==0) { /* code */ printf("I'll disconnect WiFi!\n"); break; } } // 联网业务结束 err_t ret = netifapi_dhcp_stop(iface); printf("netifapi_dhcp_stop: %d\r\n", ret); Disconnect(); // disconnect with your AP RemoveDevice(netId); // remove AP config errCode = DisableWifi(); printf("DisableWifi: %d\r\n", errCode); osDelay(200); } } void TcpServerTask(void* arg){ (void) arg; start_sta_mode(); // tcp_server_demo(); } void TcpServerEntry(void){ osThreadAttr_t attr; attr.name = "TcpServerTask"; attr.attr_bits = 0U; attr.cb_mem = NULL; attr.cb_size = 0U; attr.stack_mem = NULL; attr.stack_size = 10240; attr.priority = osPriorityNormal; if (osThreadNew(TcpServerTask, NULL, &attr) == NULL) { printf("[WifiConnectDemo] Falied to create TcpServerTask!\n"); } } SYS_RUN(TcpServerEntry);
在applications/sample/wifi-iot/app下新建socket_demo文件夹,然后添加BUILD.gn文件,这里需要把封装WiFi功能模块的文件包含进去:
BUILD.gn
static_library("socket_demo") {
sources = [
"tcp_server_test.c",
]
include_dirs = [
"//utils/native/lite/include",
"//kernel/liteos_m/components/cmsis/2.0",
"//base/iot_hardware/interfaces/kits/wifiiot_lite",
"//foundation/communication/interfaces/kits/wifi_lite/wifiservice",
"//vendor/hisi/hi3861/hi3861/third_party/lwip_sack/include/",
"//foundation/communication/wifi_lite/interfaces/wifiservice",
"//applications/sample/wifi-iot/app/wifi_demo",
]
}
3、最后修改applications/sample/wifi-iot/app/BUILD.gn文件:
import("//build/lite/config/component/lite_component.gni")
lite_component("app") {
features = [
"wifi_demo",
"socket_demo",
]
}
4、最后编译烧录即可,自己可以编写一个TCP客户端去连接服务端进行测试,作为学习HarmonyOS的新手,还有许多不足,欢迎大家留言补充,共同学习成长!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。