做网站使用明星照片可以吗,怎么做一个盈利网站,软件系统设计流程,常德网警本篇使用的是lwip编写tcp服务端。需要提前准备好一个PARAM_HOTSPOT_SSID宏定义的热点#xff0c;并且密码为PARAM_HOTSPOT_PSK
LwIP简介
LwIP是什么#xff1f;
A Lightweight TCP/IP stack 一个轻量级的TCP/IP协议栈
详细介绍请参考LwIP项目官网#xff1a;lwIP - A Li…本篇使用的是lwip编写tcp服务端。需要提前准备好一个PARAM_HOTSPOT_SSID宏定义的热点并且密码为PARAM_HOTSPOT_PSK
LwIP简介
LwIP是什么
A Lightweight TCP/IP stack 一个轻量级的TCP/IP协议栈
详细介绍请参考LwIP项目官网lwIP - A Lightweight TCP/IP stack - Summary [Savannah]
LwIP在openharmony上的应用情况
目前openharmony源码树有两份LwIP
third_party/lwip 源码形式编译供liteos-a内核使用还有一部分代码在kernel/liteos_a中一起编译
vendor/hisi/hi3861/hi3861/third_party/lwip_sack hi3861-sdk的一部分静态库形式编译不可修改配置可以查看当前配置vend
LwIP Socket API编程主要是6个步骤
创建Tcp Server Socketsocket
绑定指定的IP和Portbind
设置socket为监听状态listen
阻塞方式等待client连接accept
阻塞方式receive client的消息recv
调用send发送消息给TCP Client
修改网络参数
在Hi3861开发板上运行上述四个测试程序之前需要根据你的无线路由、Linux系统IP修改 net_params.h文件的相关代码
PARAM_HOTSPOT_SSID 修改为你的热点名称PARAM_HOTSPOT_PSK 修改为你的热点密码
代码编写
修改D:\DevEcoProjects\test\src\vendor\rtplay\rt_hi3861\demo\BUILD.gn文件
# Copyright (c) 2023 Beijing HuaQing YuanJian Education Technology Co., Ltd
# Licensed under the Apache License, Version 2.0 (the License);
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an AS IS BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License. import(//build/lite/config/component/lite_component.gni)lite_component(demo) {features [#base_00_helloworld:base_helloworld_example,#base_01_led:base_led_example,#base_02_loopkey:base_loopkey_example,#base_03_irqkey:base_irqkey_example,#base_04_adc:base_adc_example,#base_05_pwm:base_pwm_example,#base_06_ssd1306:base_ssd1306_example,#kernel_01_task:kernel_task_example,#kernel_02_timer:kernel_timer_example,#kernel_03_event:kernel_event_example,#kernel_04_mutex:kernel_mutex_example,#kernel_05_semaphore_as_mutex:kernel_semaphore_as_mutex_example,#kernel_06_semaphore_for_sync:kernel_semaphore_for_sync_example,#kernel_07_semaphore_for_count:kernel_semaphore_for_count_example,#kernel_08_message_queue:kernel_message_queue_example,#wifi_09_hotspot:wifi_hotspot_example,#wifi_10_sta:wifi_sta_example,tcp_11_server:tcp_server_example,]
}
创建D:\DevEcoProjects\test\src\vendor\rtplay\rt_hi3861\demo\tcp_11_server文件夹
文件夹中创建D:\DevEcoProjects\test\src\vendor\rtplay\rt_hi3861\demo\tcp_11_server\BUILD.gn文件
#Copyright (C) 2021 HiHope Open Source Organization .
#Licensed under the Apache License, Version 2.0 (the License);
#you may not use this file except in compliance with the License.
#You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
#Unless required by applicable law or agreed to in writing, software
#distributed under the License is distributed on an AS IS BASIS,
#WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#See the License for the specific language governing permissions and
#
#limitations under the License.static_library(tcp_server_example) {# uncomment one of following line, to enable one test:sources [tcp_server_example.c]sources [wifi_connecter.c]include_dirs [//utils/native/lite/include,//kernel/liteos_m/kal,//foundation/communication/wifi_lite/interfaces/wifiservice,]
}
添加了wifi_connecter.c文件的编译这个文件中有链接wifi的函数。
文件夹中创建D:\DevEcoProjects\test\src\vendor\rtplay\rt_hi3861\demo\tcp_11_server\net_common.h文件文件主要引入一些头文件。
/** Copyright (C) 2021 HiHope Open Source Organization .* Licensed under the Apache License, Version 2.0 (the License);* you may not use this file except in compliance with the License.* You may obtain a copy of the License at** http://www.apache.org/licenses/LICENSE-2.0** Unless required by applicable law or agreed to in writing, software* distributed under the License is distributed on an AS IS BASIS,* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.* See the License for the specific language governing permissions and** limitations under the License.*/#ifndef NET_COMMON_H
#define NET_COMMON_H// __arm__ and __aarch64__ for HarmonyOS with liteos-a kernel
// __i386__ and __x86_64__ for Unix like OS
#if defined(__arm__) || defined(__aarch64__) || defined(__i386__) || defined(__x86_64__)
#define HAVE_BSD_SOCKET 1
#else
#define HAVE_BSD_SOCKET 0
#endif#if defined(__riscv) // for wifiiot(HarmonyOS on Hi3861 with liteos-m kernel)
#define HAVE_LWIP_SOCKET 1
#else
#define HAVE_LWIP_SOCKET 0
#endif#if HAVE_BSD_SOCKET
#include sys/types.h // for AF_INET SOCK_STREAM
#include sys/socket.h // for socket
#include netinet/in.h // for sockaddr_in
#include arpa/inet.h // for inet_pton
#elif HAVE_LWIP_SOCKET
#include lwip/sockets.h
#ifndef close
#define close(fd) lwip_close(fd)
#endif
#else
#error Unknow platform!
#endif#endif // NET_COMMON_H
文件夹中创建D:\DevEcoProjects\test\src\vendor\rtplay\rt_hi3861\demo\tcp_11_server\wifi_connecter.h文件该头文件包含wifi连接的宏。
/** Copyright (C) 2021 HiHope Open Source Organization .* Licensed under the Apache License, Version 2.0 (the License);* you may not use this file except in compliance with the License.* You may obtain a copy of the License at** http://www.apache.org/licenses/LICENSE-2.0** Unless required by applicable law or agreed to in writing, software* distributed under the License is distributed on an AS IS BASIS,* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.* See the License for the specific language governing permissions and** limitations under the License.*/#ifndef WIFI_CONNECTER_H
#define WIFI_CONNECTER_H#include wifi_device.h#ifndef PARAM_HOTSPOT_SSID
#define PARAM_HOTSPOT_SSID HarmonyOS // your AP SSID
#endif#ifndef PARAM_HOTSPOT_PSK
#define PARAM_HOTSPOT_PSK 1234567890 // your AP PSK
#endif#ifndef PARAM_HOTSPOT_TYPE
#define PARAM_HOTSPOT_TYPE WIFI_SEC_TYPE_PSK // defined in wifi_device_config.h
#endif#ifndef PARAM_SERVER_ADDR
#define PARAM_SERVER_ADDR 192.168.1.100 // your PC IP address
#endif#ifndef PARAM_SERVER_PORT
#define PARAM_SERVER_PORT 5678
#endifint ConnectToHotspot(WifiDeviceConfig* apConfig);void DisconnectWithHotspot(int netId);#endif // WIFI_CONNECTER_H
文件夹中创建D:\DevEcoProjects\test\src\vendor\rtplay\rt_hi3861\demo\tcp_11_server\wifi_connecter.c文件wifi连接的实现。
/** Copyright (C) 2021 HiHope Open Source Organization .* Licensed under the Apache License, Version 2.0 (the License);* you may not use this file except in compliance with the License.* You may obtain a copy of the License at** http://www.apache.org/licenses/LICENSE-2.0** Unless required by applicable law or agreed to in writing, software* distributed under the License is distributed on an AS IS BASIS,* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.* See the License for the specific language governing permissions and** limitations under the License.*/#include wifi_device.h
#include cmsis_os2.h#include lwip/netifapi.h
#include lwip/api_shell.h#define IDX_0 0
#define IDX_1 1
#define IDX_2 2
#define IDX_3 3
#define IDX_4 4
#define IDX_5 5
#define DELAY_TICKS_10 (10)
#define DELAY_TICKS_100 (100)static 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[IDX_0], mac[IDX_1], mac[IDX_2], mac[IDX_3], mac[IDX_4], mac[IDX_5]);printf(bssid: %s, rssi: %d, connState: %d, reason: %d, ssid: %s\r\n,macAddress, info-rssi, info-connState, info-disconnectedReason, info-ssid);
}static volatile int g_connected 0;static 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;}
}static void OnWifiScanStateChanged(int state, int size)
{printf(%s %d, state %X, size %d\r\n, __FUNCTION__, __LINE__, state, size);
}static WifiEvent g_defaultWifiEventListener {.OnWifiConnectionChanged OnWifiConnectionChanged,.OnWifiScanStateChanged OnWifiScanStateChanged
};static struct netif* g_iface NULL;err_t netifapi_set_hostname(struct netif *netif, char *hostname, u8_t namelen);int ConnectToHotspot(WifiDeviceConfig* apConfig)
{WifiErrorCode errCode;int netId -1;errCode RegisterWifiEvent(g_defaultWifiEventListener);printf(RegisterWifiEvent: %d\r\n, errCode);errCode EnableWifi();printf(EnableWifi: %d\r\n, errCode);errCode AddDeviceConfig(apConfig, netId);printf(AddDeviceConfig: %d\r\n, errCode);g_connected 0;errCode ConnectTo(netId);printf(ConnectTo(%d): %d\r\n, netId, errCode);while (!g_connected) { // wait until connect to APosDelay(DELAY_TICKS_10);}printf(g_connected: %d\r\n, g_connected);g_iface netifapi_netif_find(wlan0);if (g_iface) {err_t ret 0;char* hostname rtplay;ret netifapi_set_hostname(g_iface, hostname, strlen(hostname));printf(netifapi_set_hostname: %d\r\n, ret);ret netifapi_dhcp_start(g_iface);printf(netifapi_dhcp_start: %d\r\n, ret);osDelay(DELAY_TICKS_100); // wait DHCP server give me IP
#if 1ret netifapi_netif_common(g_iface, dhcp_clients_info_show, NULL);printf(netifapi_netif_common: %d\r\n, ret);
#else// 下面这种方式也可以打印 IP、网关、子网掩码信息ip4_addr_t ip {0};ip4_addr_t netmask {0};ip4_addr_t gw {0};ret netifapi_netif_get_addr(g_iface, ip, netmask, gw);if (ret ERR_OK) {printf(ip %s\r\n, ip4addr_ntoa(ip));printf(netmask %s\r\n, ip4addr_ntoa(netmask));printf(gw %s\r\n, ip4addr_ntoa(gw));}printf(netifapi_netif_get_addr: %d\r\n, ret);
#endif}return netId;
}void DisconnectWithHotspot(int netId)
{if (g_iface) {err_t ret netifapi_dhcp_stop(g_iface);printf(netifapi_dhcp_stop: %d\r\n, ret);}WifiErrorCode errCode Disconnect(); // disconnect with your APprintf(Disconnect: %d\r\n, errCode);errCode UnRegisterWifiEvent(g_defaultWifiEventListener);printf(UnRegisterWifiEvent: %d\r\n, errCode);RemoveDevice(netId); // remove AP configprintf(RemoveDevice: %d\r\n, errCode);errCode DisableWifi();printf(DisableWifi: %d\r\n, errCode);
}
文件夹中创建D:\DevEcoProjects\test\src\vendor\rtplay\rt_hi3861\demo\tcp_11_server\tcp_server_example.c文件
/** Copyright (C) 2021 HiHope Open Source Organization .* Licensed under the Apache License, Version 2.0 (the License);* you may not use this file except in compliance with the License.* You may obtain a copy of the License at** http://www.apache.org/licenses/LICENSE-2.0** Unless required by applicable law or agreed to in writing, software* distributed under the License is distributed on an AS IS BASIS,* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.* See the License for the specific language governing permissions and** limitations under the License.*/#include errno.h
#include stdio.h
#include string.h
// #include stddef.h
#include unistd.h
#include ohos_init.h
#include cmsis_os2.h#include net_common.h
#include wifi_connecter.h#define DELAY_1S (1)
#define STACK_SIZE (10240)
#define DELAY_TICKS_10 (10)
#define DELAY_TICKS_100 (100)static char request[128] ;
void TcpServerTest(void)
{WifiDeviceConfig config {0};// 准备AP的配置参数// strcpy(config.ssid, PARAM_HOTSPOT_SSID);// strcpy(config.preSharedKey, PARAM_HOTSPOT_PSK);strcpy_s(config.ssid, WIFI_MAX_SSID_LEN, PARAM_HOTSPOT_SSID);strcpy_s(config.preSharedKey, WIFI_MAX_KEY_LEN, PARAM_HOTSPOT_PSK);config.securityType PARAM_HOTSPOT_TYPE;osDelay(DELAY_TICKS_10);int netId ConnectToHotspot(config);ssize_t retval 0;int backlog 1;int sockfd socket(AF_INET, SOCK_STREAM, 0); // TCP socketint connfd -1;struct sockaddr_in clientAddr {0};socklen_t clientAddrLen sizeof(clientAddr);struct sockaddr_in serverAddr {0};serverAddr.sin_family AF_INET;serverAddr.sin_port htons(PARAM_SERVER_PORT); // 端口号从主机字节序转为网络字节序serverAddr.sin_addr.s_addr htonl(INADDR_ANY); // 允许任意主机接入 0.0.0.0retval bind(sockfd, (struct sockaddr *)serverAddr, sizeof(serverAddr)); // 绑定端口if (retval 0) {printf(bind failed, %ld!\r\n, retval);goto do_cleanup;}printf(bind to port %hu success!\r\n, PARAM_SERVER_PORT);retval listen(sockfd, backlog); // 开始监听if (retval 0) {printf(listen failed!\r\n);goto do_cleanup;}printf(listen with %d backlog success!\r\n, backlog);// 接受客户端连接成功会返回一个表示连接的 socket clientAddr 参数将会携带客户端主机和端口信息 失败返回 -1// 此后的 收、发 都在 表示连接的 socket 上进行之后 sockfd 依然可以继续接受其他客户端的连接// UNIX系统上经典的并发模型是“每个连接一个进程”——创建子进程处理连接父进程继续接受其他客户端的连接// 鸿蒙liteos-a内核之上可以使用UNIX的“每个连接一个进程”的并发模型// liteos-m内核之上可以使用“每个连接一个线程”的并发模型connfd accept(sockfd, (struct sockaddr *)clientAddr, clientAddrLen);if (connfd 0) {printf(accept failed, %d, %d\r\n, connfd, errno);goto do_cleanup;}printf(accept success, connfd %d!\r\n, connfd);printf(client addr info: host %s, port %hu\r\n, inet_ntoa(clientAddr.sin_addr), ntohs(clientAddr.sin_port));// 后续 收、发 都在 表示连接的 socket 上进行retval recv(connfd, request, sizeof(request), 0);if (retval 0) {printf(recv request failed, %ld!\r\n, retval);goto do_disconnect;}printf(recv request{%s} from client done!\r\n, request);retval send(connfd, request, strlen(request), 0);if (retval 0) {printf(send response failed, %ld!\r\n, retval);goto do_disconnect;}printf(send response{%s} to client done!\r\n, request);do_disconnect:sleep(DELAY_1S);close(connfd);sleep(DELAY_1S); // for debugdo_cleanup:printf(do_cleanup...\r\n);close(sockfd);DisconnectWithHotspot(netId);
}SYS_RUN(TcpServerTest);
使用build编译成功后使用upload进行烧录。