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:
- 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 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进行烧录。



相关文章:
Hi3861 OpenHarmony嵌入式应用入门--TCP Server
本篇使用的是lwip编写tcp服务端。需要提前准备好一个PARAM_HOTSPOT_SSID宏定义的热点,并且密码为PARAM_HOTSPOT_PSK LwIP简介 LwIP是什么? A Lightweight TCP/IP stack 一个轻量级的TCP/IP协议栈 详细介绍请参考LwIP项目官网:lwIP - A Li…...
Poker Game, Run Fast
Poker Game, Run Fast 扑克:跑得快 分门别类: 单张从小到大默认 A < 2 < 3 < 4 < 5 < 6 < 7 < 8 < 9 < 10 < J < Q < K 跑得快:单张从小到大 3 < 4 < 5 < 6 < 7 < 8 < 9 < 10 &…...
订单折扣金额分摊算法|代金券分摊|收银系统|积分分摊|分摊|精度问题|按比例分配|钱分摊|钱分配
一个金额分摊的算法,将折扣分摊按比例(细单实收在总体的占比)到各个细单中。 此算法需要达到以下要求: 折扣金额接近细单总额,甚至折扣金额等于细单金额,某些时候甚至超过细单总额,要保证实收不…...
Matlab中collectPlaneWave函数的应用
查看文档如下: 可以看出最多5个参数,分别是阵列对象,信号幅度,入射角度,信号频率,光速。 在下面的代码中,我们先创建一个3阵元的阵列,位置为:(-1,0,0&#x…...
Linux系统的基础知识和常用命令
1、什么是Linux? 是一种免费使用和自由传播的类UNIX操作系统,其内核由林纳斯本纳第克特托瓦兹于1991年10月5日首次发布,它主要受到Minix和Unix思想的启发,是一个基于POSIX的多用户、多任务、支持多线程和多CPU的操作系统。它能运行…...
三相异步电动机的起动方法
1. 引言 2. 三相笼型异步电动机德起动方法 3. 三相绕线型异步电动机的起动方法 4. 软起动器起动 5. 参考文献 1 引言 三相异步电动机结构简单﹑价格低廉﹑运行可靠﹑维护方便,在工农业生产中得到了广泛应用。为使电动机能够转动起来,并很快达到工作转…...
【LinuxC语言】手撕Http协议之accept_request函数实现(一)
文章目录 前言accept_request函数作用accept_request实现解析方法根据不同方法进行不同操作http服务器响应格式unimplemented函数实现总结前言 在计算机网络中,HTTP协议是一种常见的应用层协议,它定义了客户端和服务器之间如何进行数据交换。在这篇文章中,我们将深入探讨Li…...
Redis Cluster 模式 的具体实施细节是什么样的?
概述 参考:What are Redis Cluster and How to setup Redis Cluster locally ? | by Rajat Pachauri | Medium Redis Cluster 的工作原理是将数据分布在多个节点上,同时确保高可用性和容错能力。以下是 Redis Cluster 运行方式的简要概述: …...
基于大模型的机器人控制
基于大模型的机器人控制是指利用深度学习中的大型神经网络模型来实现对机器人的精确控制。这种方法结合了深度学习的强大表征学习能力和机器人控制的实际需求,旨在提高机器人的自主性、灵活性和智能性。 基本原理 数据收集:首先,需要收集大量…...
在 PostgreSQL 中,如何处理数据的版本控制?
文章目录 一、使用时间戳字段进行版本控制二、使用版本号字段进行版本控制三、使用历史表进行版本控制四、使用 RETURNING 子句获取更新前后的版本五、使用数据库触发器进行版本控制 在 PostgreSQL 中,处理数据的版本控制可以通过多种方式实现,每种方式都…...
Rust 组织管理
Rust 组织管理 Rust 是一种系统编程语言,以其内存安全性、速度和并发性而闻名。它由 Mozilla 开发,并得到了一个庞大而活跃的社区的支持。Rust 的组织管理涉及多个方面,包括项目管理、社区参与、工具和库的维护,以及生态系统的整…...
vb.netcad二开自学笔记1:万里长征第一步Hello CAD!
已入门的朋友请绕行! 今天开启自学vb.net 开发autocad,网上相关资料太少了、太老了。花钱买课吧,穷!又舍不得,咬牙从小白开始摸索自学吧,虽然注定是踏上了一条艰苦之路,顺便作个自学笔记备忘!积…...
Vue的学习之数据与方法
前段期间,由于入职原因没有学习,现在已经正式入职啦,接下来继续加油学习。 一、数据与方法 文字备注已经在代码中,方便自己学习和理解 <!DOCTYPE html> <html><head><meta charset"utf-8">&l…...
刷题——在二叉树中找到最近公共祖先
在二叉树中找到两个节点的最近公共祖先_牛客题霸_牛客网 int lowestCommonAncestor(TreeNode* root, int o1, int o2) {if(root NULL) return -1;if((root->val o1) || (root->val o2)) return root->val;int left lowestCommonAncestor(root->left, o1, o2);i…...
nginx(三)—从Nginx配置熟悉Nginx功能
一、 Nginx配置文件结构 ... #全局块events { #events块... }http #http块 {... #http全局块server #server块{ ... #server全局块location [PATTERN] #location块{...}location [PATTERN] {...}}server{...}... #http全局块 …...
Python轮子:文件比较器——filecmp
原文链接:http://www.juzicode.com/python-module-filecmp filecmp模块可以用来比较文件或者目录。 安装和导入 filecmp是Python自带的模块,不需要额外安装,直接导入即可: import filecmp as fc #或者 import filecmp cmp()比较…...
uni-app组件 子组件onLoad、onReady事件无效
文章目录 导文解决方法 导文 突然发现在项目中,组件 子组件的onLoad、onReady事件无效 打印也出不来值 怎么处理呢? 解决方法 mounted() {console.log(onLoad, this.dateList);//有效// this.checkinDetails()},onReady() {console.log(onReady, this.da…...
leetcode力扣_排序问题
215.数组中的第K个最大元素 鉴于已经将之前学的排序算法忘得差不多了,只会一个冒泡排序法了,就写了一个冒牌排序法,将给的数组按照降序排列,然后取nums[k-1]就是题目要求的,但是提交之后对于有的示例显示”超出时间限制…...
在 .NET 8 Web API 中实现弹性
在现代 Web 开发中,构建弹性 API 对于确保可靠性和性能至关重要。本文将指导您使用 Microsoft.Extensions.Http.Resilience 库在 .NET 8 Web API 中实现弹性。我们将介绍如何设置重试策略和超时,以使您的 API 更能抵御瞬时故障。 步骤 1.创建一个新的 .…...
linux下高级IO模型
高级IO 1.高级IO模型基本概念1.1 阻塞IO1.2 非阻塞IO1.3 信号驱动IO1.4 IO多路转接1.5 异步IO 2. 模型代码实现2.1 非阻塞IO2.2 多路转接-selectselect函数介绍什么才叫就绪呢?demoselect特点 2.3 多路转接-pollpoll函数介绍poll优缺点demo 2.4 多路转接-epoll&…...
【网络】每天掌握一个Linux命令 - iftop
在Linux系统中,iftop是网络管理的得力助手,能实时监控网络流量、连接情况等,帮助排查网络异常。接下来从多方面详细介绍它。 目录 【网络】每天掌握一个Linux命令 - iftop工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景…...
Cesium1.95中高性能加载1500个点
一、基本方式: 图标使用.png比.svg性能要好 <template><div id"cesiumContainer"></div><div class"toolbar"><button id"resetButton">重新生成点</button><span id"countDisplay&qu…...
汽车生产虚拟实训中的技能提升与生产优化
在制造业蓬勃发展的大背景下,虚拟教学实训宛如一颗璀璨的新星,正发挥着不可或缺且日益凸显的关键作用,源源不断地为企业的稳健前行与创新发展注入磅礴强大的动力。就以汽车制造企业这一极具代表性的行业主体为例,汽车生产线上各类…...
学校招生小程序源码介绍
基于ThinkPHPFastAdminUniApp开发的学校招生小程序源码,专为学校招生场景量身打造,功能实用且操作便捷。 从技术架构来看,ThinkPHP提供稳定可靠的后台服务,FastAdmin加速开发流程,UniApp则保障小程序在多端有良好的兼…...
多模态大语言模型arxiv论文略读(108)
CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文标题:CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文作者:Sayna Ebrahimi, Sercan O. Arik, Tejas Nama, Tomas Pfister ➡️ 研究机构: Google Cloud AI Re…...
稳定币的深度剖析与展望
一、引言 在当今数字化浪潮席卷全球的时代,加密货币作为一种新兴的金融现象,正以前所未有的速度改变着我们对传统货币和金融体系的认知。然而,加密货币市场的高度波动性却成为了其广泛应用和普及的一大障碍。在这样的背景下,稳定…...
Oracle11g安装包
Oracle 11g安装包 适用于windows系统,64位 下载路径 oracle 11g 安装包...
软件工程 期末复习
瀑布模型:计划 螺旋模型:风险低 原型模型: 用户反馈 喷泉模型:代码复用 高内聚 低耦合:模块内部功能紧密 模块之间依赖程度小 高内聚:指的是一个模块内部的功能应该紧密相关。换句话说,一个模块应当只实现单一的功能…...
【WebSocket】SpringBoot项目中使用WebSocket
1. 导入坐标 如果springboot父工程没有加入websocket的起步依赖,添加它的坐标的时候需要带上版本号。 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId> </dep…...
STM32标准库-ADC数模转换器
文章目录 一、ADC1.1简介1. 2逐次逼近型ADC1.3ADC框图1.4ADC基本结构1.4.1 信号 “上车点”:输入模块(GPIO、温度、V_REFINT)1.4.2 信号 “调度站”:多路开关1.4.3 信号 “加工厂”:ADC 转换器(规则组 注入…...
