Hi3861 OpenHarmony嵌入式應用入門--TCP Server

本篇使用的是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:

  1. third_party/lwip
    • 源碼形式編譯
    • 供liteos-a內核使用
    • 還有一部分代碼在kernel/liteos_a中,一起編譯
  1. vendor/hisi/hi3861/hi3861/third_party/lwip_sack
    • hi3861-sdk的一部分
    • 靜態庫形式編譯
    • 不可修改配置
    • 可以查看當前配置(vend

LwIP Socket API編程主要是6個步驟:

創建Tcp Server Socket:socket

綁定指定的IP和Port:bind

設置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進行燒錄。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/42131.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/42131.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/42131.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

主流I/O模型總結

異步通知I/O模型(Windows) #include<string.h> #include<stdio.h> #include<WinSock2.h> #define BUF_SIZE 100 void CompressSockets(SOCKET hSockArr[], int idx, int total); void CompressEvent(WSAEVENT hEventArr[], int idx, int total); char msg[B…

奇景光電戰略投資Obsidian,共筑熱成像技術新未來

5月29日,業界領先的IC設計公司奇景光電宣布,將對熱成像傳感器解決方案制造商Obsidian進行戰略性投資,并以主要投資者的身份,參與到Obsidian的可轉換票據融資活動中。雖然奇景光電并未公開具體的投資金額,但這一舉動無疑向市場傳遞了一個明確的信號:奇景光電對Obsidian的技…

【INTEL(ALTERA)】為什么我會看到包含管道橋的Nios II設計出現 Flash Programmer 問題?

目錄 說明 解決方法 說明 簡化地址解碼的常見解決方案是將連接到Avalon管道橋后Nios II處理器的數據主的外設放置&#xff0c;有時可能包括一些內存 IP&#xff0c;如片上 RAM。 但是&#xff0c;如果預期內存包含Nios II程序代碼&#xff0c;則應該以與Nios II指令主連接到…

10、matlab中字符、數字、矩陣、字符串和元胞合并為字符串并將字符串以不同格式寫入讀出excel

1、前言 在 MATLAB 中&#xff0c;可以使用不同的數據類型&#xff08;字符、數字、矩陣、字符串和元胞&#xff09;合并為字符串&#xff0c;然后將字符串以不同格式寫入 Excel 文件。 以下是一個示例代碼&#xff0c;展示如何將不同數據類型合并為字符串&#xff0c;并以不…

【Mindspore進階】-03.ShuffleNet實戰

ShuffleNet圖像分類 當前案例不支持在GPU設備上靜態圖模式運行&#xff0c;其他模式運行皆支持。 ShuffleNet網絡介紹 ShuffleNetV1是曠視科技提出的一種計算高效的CNN模型&#xff0c;和MobileNet, SqueezeNet等一樣主要應用在移動端&#xff0c;所以模型的設計目標就是利用有…

如何在Java中實現自動化測試和集成測試

如何在Java中實現自動化測試和集成測試 大家好&#xff0c;我是免費搭建查券返利機器人省錢賺傭金就用微賺淘客系統3.0的小編&#xff0c;也是冬天不穿秋褲&#xff0c;天冷也要風度的程序猿&#xff01; 自動化測試和集成測試是現代軟件開發過程中至關重要的環節。Java作為一…

分享實現地鐵車輛側面圖

簡介 通過偽類和關鍵幀動畫實現地鐵車輛側面圖 在線演示 偽元素和關鍵幀動畫 實現代碼 <!DOCTYPE html><html><head> <meta http-equiv"Content-Type" content"text/html; charsetutf-8" /> <meta http-equiv"X-UA-Co…

設計模式之單例模式(Java)

單例模式實現方式&#xff1a;懶漢式、餓漢式、雙重檢查、枚舉、靜態內部類&#xff1b; 懶漢式&#xff1a; /*** 懶漢式單例模式* author: 小手WA涼* create: 2024-07-06*/ public class LazySingleton implements Serializable {private static LazySingleton lazySinglet…

對BSV區塊鏈的曼達拉網絡通俗易懂的解釋

??發表時間&#xff1a;2023年6月15日 BSV區塊鏈正在引入“曼達拉”升級&#xff0c;使BSV區塊鏈網絡的拓撲結構能夠適配Teranode&#xff0c;適配這個可以大幅擴容的節點軟件。BSV區塊鏈上曼達拉網絡的概念并不會改變整個系統的核心規則&#xff1b;相反&#xff0c;它能夠引…

為什么https比http更安全

讀完本文&#xff0c;希望你能明白&#xff1a; HTTP通信存在什么問題HTTPS如何改進HTTP存在那些問題HTTPS工作原理是什么 一、什么是HTTPS HTTPS是在HTTP上建立SSL加密層&#xff0c;并對傳輸數據進行加密&#xff0c;是HTTP協議的安全版。現在它被廣泛用于萬維網上安全敏感…

【qt】如何獲取本機的IP地址?

需要用到這個類QHostInfo和pro里面添加network模塊 用這個類的靜態函數forName()來獲取該主機名的信息 返回的就是這個類 這個QHostInfo類就包括主機的IP地址信息 用靜態函數addresses()來獲取 返回的是一個QHostAddress的容器 QList<QHostAddress>addrList hostIn…

Laravel隊列機制深度解析:異步任務處理的高效之道

Laravel隊列機制深度解析&#xff1a;異步任務處理的高效之道 Laravel的隊列系統是一個強大的工具&#xff0c;用于執行后臺任務和異步處理。它允許開發者將耗時的任務&#xff0c;如發送郵件、處理圖片等&#xff0c;放入隊列中&#xff0c;然后由后臺工作進程異步執行。本文…

Docker 鏡像移動或復制到另一臺服務器

在實際的開發和部署過程中&#xff0c;我們可能需要將 Docker 鏡像從一臺服務器移動或復制到另一臺服務器。本文將詳細介紹如何實現這一操作&#xff0c;幫助你更好地管理和遷移 Docker 鏡像。 一、使用 docker save 和 docker load 命令 docker save 和 docker load 是 Dock…

課題申報書中要用的思路圖(技術路線圖)30張,超高清!

最近在弄課題申報書的時候&#xff0c;需要畫“技術路線圖”&#xff1b;和小伙伴們探討才發現很多人居然不會畫這種圖&#xff0c;還有很多人在Word里面一點一點拼湊…… 我給大家收集了網上非常熱門的30張“技術路線圖”&#xff0c;但網上流傳的都太模糊了&#xff0c;想看…

KBPC3506-ASEMI儲能專用整流橋KBPC3506

編輯&#xff1a;ll KBPC3506-ASEMI儲能專用整流橋KBPC3506 型號&#xff1a;KBPC3506 品牌&#xff1a;ASEMI 封裝&#xff1a;KBPC-4 正向電流&#xff08;Id&#xff09;&#xff1a;35A 反向耐壓&#xff08;VRRM&#xff09;&#xff1a;600V 正向浪涌電流&#xf…

基于RK3588的8路攝像頭實時全景拼接

基于RK3588的8路攝像頭實時全景拼接 輸入&#xff1a;2路csi轉8路mpi的ahd攝像頭&#xff0c;分辨率1920 * 1080 8路拼接結果&#xff1a; 6路拼接結果&#xff1a; UI界面&#xff1a; UI節目設計原理

SpringBoot新手快速入門系列教程一:window上編程環境安裝和配置

首先編譯器&#xff0c;建議各位不要去嘗試AndroidStudio和VisualStudio來做SpringBoot項目。乖乖的直接下載最新版即可 https://www.jetbrains.com.cn/idea/ 當然這是一個收費的IDE&#xff0c;想要便宜可以想辦法去某寶買授權&#xff0c;僅供學習參考用&#xff01;賺了錢…

Spring Boot中的多租戶架構實現

Spring Boot中的多租戶架構實現 大家好&#xff0c;我是免費搭建查券返利機器人省錢賺傭金就用微賺淘客系統3.0的小編&#xff0c;也是冬天不穿秋褲&#xff0c;天冷也要風度的程序猿&#xff01; 一、引言 隨著云計算和SaaS&#xff08;軟件即服務&#xff09;模式的流行&a…

Matlab中collectPlaneWave函數的應用

查看文檔如下&#xff1a; 可以看出最多5個參數&#xff0c;分別是陣列對象&#xff0c;信號幅度&#xff0c;入射角度&#xff0c;信號頻率&#xff0c;光速。 在下面的代碼中&#xff0c;我們先創建一個3陣元的陣列&#xff0c;位置為&#xff1a;&#xff08;-1,0,0&#x…

52-3 權限維持 - IFEO注入(鏡像劫持)

IFEO注入(映像劫持)介紹 IFEO(Image File Execution Options)位于Windows注冊表中的路徑為: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options IFEO最初設計用于為在默認系統環境下可能出現錯誤的程序提供特殊的調試和執…