当前位置: 首页 > news >正文

嵌入式学习第二十五天!(网络的概念、UDP编程)

网络:

    可以用来:数据传输数据共享

1. 网络协议模型:

    1. OSI协议模型:

应用层实际收发的数据
表示层发送的数据是否加密
会话层是否建立会话连接
传输层数据传输的方式(数据包,流式)
网络层数据的路由(如何从一个局域网到达另一个局域网)
数据链路层局域网下如何通信
物理层物理介质的连接

      2. TCP/IP协议模型:

应用层传输的数据
传输层传输的方式
网络层数据如何从一个台主机到达另一台主机
网络接口层物理介质的连接
        1. 应用层:

               例如有:HTTP      超文本传输协议

                              HTTPS   

                              FTP        文件传输协议

                              TFTP      简单文本传输协议

                              SMTP     邮件传输协议

                              MQTT

                              TELNET

                              ...

        2. 传输层:

              UDP:用户数据报协议

                    特点:1. 实现机制简单

                               2. 资源开销小

                               3. 不安全不可靠

              TCP:传输控制协议

                      特点:1. 实现机制复杂

                                 2. 资源开销大

                                 3. 安全可靠

        3. 网络层:

              IPv4

              IP地址:唯一网络中一台主机的标号

              IP地址:网络位 + 主机位

              子网掩码:用来标识IP地址的网络位和主机位

                                子网掩码是1的部分表示IP地址的网络位

                                子网掩码是0的部分表示IP地址的主机位

                网段号:网络位不变,主机位全位0,表示网段号

                广播地址:网络位不变,主机位全为1,表示广播地址

                IP地址类型:

                A类:

                        1.0.0.0  -  126.255.255.255

                        子网掩码:255.0.0.0

                        管理超大规模网络

                        私有IP地址:10.0.0.0  -  10.255.255.255

                B类:

                        128.0.0.0  -  191.255.255.255

                        子网掩码:255.255.0.0

                        管理大中规模型网络

                        私有IP地址:172.16.0.0  -  172.31.255.255

                C类:

                        192.0.0.0  -  223.255.255.255

                        子网掩码:255.255.255.0

                        管理中小规模型网络

                        私有IP地址:192.168.0.0  -  192.168.255.255

                D类:

                        224.0.0.0  -  239.0.0.0

                        用于组播

                E类:

                        240.0.0.0  -  255.255.255.255

                        用于实验

        4. UDP编程:

            socket套接字(全双工)编程:

            发端:socket  ->  sendto  ->  close

            收端:socket  ->  bind  ->  recvfrom  ->  close

            1. 发端
                1. socket:
int socket(int domain, int type, int protocol);

                    功能:创建一个用来通信的文件描述符

                    参数:

                        domain:使用的协议族 AF_INET(IPv4协议族)

                        type:套接字类型

                                SOCK_STREAM:流式套接字

                                SOCK_DGRAM:数据报套接字

                                SOCK_RAW:原始套接字

                        protocol:协议

                                默认为0;

                    返回值:

                        成功返回文件描述符
                        失败返回-1

                2. sendto:
ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,const struct sockaddr *dest_addr, socklen_t addrlen);

                    功能:利用套接字向指定地址发送数据信息

                    参数:

                        sockfd:套接字文件描述符

                        buf:发送数据空间首地址

                        len:发送数据的长度

                        flags:属性默认为0

                        dest_addr:目的地址信息存放的空间首地址

                        addrlen:目的地址的长度

struct sockaddr_in {sa_family_t    sin_family; /* address family: AF_INET */in_port_t      sin_port;   /* port in network byte order */struct in_addr sin_addr;   /* internet address */
};/* Internet address. */
struct in_addr {uint32_t       s_addr;     /* address in network byte order */
};

                    返回值:

                        成功返回实际发送字节数
                        失败返回-1

                3. inet_addr:
in_addr_t inet_addr(const char *cp);

                    功能:将字符串IP地址转换为内存中的IP地址

                4. htons:
uint16_t htons(uint16_t hostshort);

                    功能:将本地字节序转换为网络的大端字节序

            练习:

                1. 编写程序实现从终端接收字符串发送给windows软件调试助手,并接收软件助手的回复,显示在终端屏幕上

#include "head.h"int main(void)
{int sockfd = 0;ssize_t nsize = 0;char tmpbuff[1024] = {0};struct sockaddr_in recvaddr;sockfd = socket(AF_INET, SOCK_DGRAM, 0);if(sockfd == -1){perror("fail to socket");return -1;}gets(tmpbuff);recvaddr.sin_family = AF_INET;recvaddr.sin_port = htons(50000);recvaddr.sin_addr.s_addr = inet_addr("192.168.1.162");bind(sockfd, (struct sockaddr *)&recvaddr, sizeof(&recvaddr));nsize = sendto(sockfd, tmpbuff, strlen(tmpbuff), 0, (struct sockaddr *)&recvaddr, sizeof(recvaddr));if(nsize == -1){perror("fail to sendto");return -1;}printf("成功发送 %ld 字节!\n", nsize);memset(tmpbuff, 0, sizeof(tmpbuff));nsize = recvfrom(sockfd, tmpbuff, sizeof(tmpbuff), 0, (struct sockaddr *)&recvaddr, (socklen_t *)sizeof(&recvaddr));printf("%s\n",tmpbuff);close(sockfd);return 0;
}
             2. 收端
                1. recvfrom:
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,struct sockaddr *src_addr, socklen_t *addrlen);

                    功能:从套接字中接收数据

                    参数:

                        sockfd:套接字文件描述符

                        buf:存放数据空间首地址

                        flags:属性,默认为0

                        src_addr:存放IP地址信息的空间首地址

                        addlen:存放接收到IP地址大小空间的首地址

                    返回值:

                        成功返回实际接收字节数
                        失败返回-1 

                2. 修改虚拟机到桥接模式:

                    点击“虚拟机”

                    点击“设置”

                    点击“网络适配器”

                    选择“桥接模式”

                    点击“确定”

                3. 将网卡桥接到无线网卡:

                    点击“编辑”

                    点击“虚拟网络编辑器”

                    点击“更改设置”

                4. 在Ubuntu中重启网络服务:
sudo /etc/init.d/networking restart 
                5. 通过ifconfig查看虚拟机IP地址
                6. bind:
int bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen);

                    功能:在套接字上绑定一个IP地址和端口号

                    参数:

                        sockfd:套接字文件描述符

                        addr:绑定IP地址空间首地址

                        addrlen:绑定IP地址的长度

                    返回值:

                        成功返回0 
                        失败返回-1 

            3. UDP需要注意的细节点:

                1. UDP是无连接,发端退出,收端没有任何影响

                2. UDP发送数据上限,最好不要超过1500个字节

                3. UDP是不安全不可靠的,连续且快速的传输数据容易产生数据丢失

            4. wireshark

                可以通过wireshark抓包工具来查看收发的数据

                操作流程:

                    1. 打开wireshark:

sudo wireshark

                    2. 选择抓取数据包的网卡:any

                    3. 执行通信的代码

                    4. 停止通信

                    5. 设定过滤条件

                        ip.addr == IP地址  :通过IP地址查找

                        udp                        :通过传输方式udp查找

                        tcp                         :通过传输方式tcp查找

                        udp.port == 端口号:通过端口号查找

            5. UDP包头长度:8个字节

                源端口号(2个字节)

                目的端口号(2个字节)

                长度(2个字节)

                检验和(2个字节)

            练习:

                要求在不同主机中编写两个程序,实现全双工聊天功能

                1. 进入软件后接收当前用户的昵称

                2. 显示的格式为对方用户昵称 (对方IP:对方端口) > 接收到的内容

                3. 用户输入“.quit”退出聊天

                4. 网络通信时收发结构体

struct person 
{char name[32];char text[512];
};
#include "head.h"int sockfd = 0;
ssize_t nsize = 0;
struct sockaddr_in tmpaddr;
struct sockaddr_in sendaddr;
socklen_t addrlen = sizeof(tmpaddr);struct person
{char name[32];char text[512];
};pthread_t tid_recv;
pthread_t tid_send;void *RecvInfo(void *arg)
{struct person user;while(1){memset(&user, 0, sizeof(user));nsize = recvfrom(sockfd, &user, sizeof(user), 0, (struct sockaddr *)&tmpaddr, &addrlen);if(nsize == -1){perror("fail to recvfrom");return NULL;}printf("%s %s : %d > %s\n", user.name, inet_ntoa(tmpaddr.sin_addr), ntohs(tmpaddr.sin_port), user.text);if(!strcmp(user.text, ".quit")){break;}}pthread_cancel(tid_send);return NULL;
}void *SendInfo(void *arg)
{struct person user;while(1){memset(&user, 0, sizeof(user));scanf("%s", user.name);scanf("%s", user.text);nsize = sendto(sockfd, &user, sizeof(user), 0, (struct sockaddr *)&sendaddr, sizeof(sendaddr));if(nsize == -1){perror("fail to sendto");return NULL;}printf("success send %ld byte\n", nsize);if(!strcmp(user.text, ".quit")){break;}}pthread_cancel(tid_recv);return NULL;
}int main(void)
{struct sockaddr_in recvaddr;sockfd = socket(AF_INET, SOCK_DGRAM, 0);if(sockfd == -1){perror("fail to socket");return -1;}recvaddr.sin_family = AF_INET;recvaddr.sin_port = htons(30000);recvaddr.sin_addr.s_addr = inet_addr("192.168.1.153");bind(sockfd, (struct sockaddr *)&recvaddr, sizeof(recvaddr));sendaddr.sin_family = AF_INET;sendaddr.sin_port = htons(30000);sendaddr.sin_addr.s_addr = inet_addr("192.168.1.152");pthread_create(&tid_recv, NULL, RecvInfo, NULL);pthread_create(&tid_send, NULL, SendInfo, NULL);pthread_join(tid_recv, NULL);pthread_join(tid_send, NULL);close(sockfd);return 0;}
        5. UDP项目练习:

        题目:基于UDP实现直播间聊天的功能:

        需求:

                软件划分为用户客户端和主播服务端两个软件client.c和server.c

                用户客户端负责:

                        1.接收用户的昵称
                        2.接收用户输入的信息,能够将信息发送给服务端
                        3.接收服务端回复的数据信息,并完成显示

                主播服务端负责:

                        1.对所有加入直播间的用户的IP地址和端口实现管理(加入、退出)
                        2.当有新的客户端加入时,能够向所有客户端提示:"欢迎 XXX 用户进入直播间"
                        3.当有客户端退出时,能够向所有客户端提示:"XXX 离开直播间"
                        4.能够实现客户端聊天内容的转发,当某个客户端发送聊天信息时,能够将该信息转给除了该用户之外聊天室内所有其余客户端用户

client.c

#include "head.h"int sockfd = 0;
char name[32];
struct sockaddr_in recvaddr;
pthread_t tid_send;
pthread_t tid_recv;void *SendMsg(void *arg)
{struct msgbuf sendmsg;ssize_t nsize = 0;while(1){memset(&sendmsg, 0, sizeof(sendmsg)); sendmsg.type = USER_TYPE_CHAT;sprintf(sendmsg.name, "%s", name);gets(sendmsg.text);if(strcmp(sendmsg.text,".quit") == 0){sendmsg.type = USER_TYPE_OUT;}nsize = sendto(sockfd, &sendmsg, sizeof(sendmsg), 0, (struct sockaddr *)&recvaddr, sizeof(recvaddr));if(nsize == -1){perror("fail to sendto");return NULL;}if(sendmsg.type == USER_TYPE_OUT){break;}}pthread_cancel(tid_recv);return NULL;
}void *RecvMsg(void *arg)
{struct msgbuf recvmsg;ssize_t nsize = 0;while(1){nsize = recvfrom(sockfd, &recvmsg, sizeof(recvmsg), 0, NULL, NULL);if(nsize == -1){perror("fail to recvfrom");return NULL;}if(recvmsg.type == USER_TYPE_CHAT){printf("%s>%s\n", recvmsg.name, recvmsg.text);}if(recvmsg.type == USER_TYPE_OUT){break;}}return NULL;
}int main(void)
{ssize_t nsize = 0;struct msgbuf sendmsg; sockfd = socket(AF_INET, SOCK_DGRAM, 0);if(sockfd == -1){perror("fail to socket");return -1;}printf("请输入你的名字:\n");gets(name);memset(&sendmsg, 0, sizeof(sendmsg));sendmsg.type = USER_TYPE_INT;sprintf(sendmsg.name, "%s", name);recvaddr.sin_family = AF_INET;recvaddr.sin_port = htons(SERVER_PORT);recvaddr.sin_addr.s_addr = inet_addr(SERVER_ADDR);nsize = sendto(sockfd, &sendmsg, sizeof(sendmsg), 0, (struct sockaddr *)&recvaddr, sizeof(recvaddr));if(nsize == -1){perror("fail to sendto");return -1;}pthread_create(&tid_send, NULL, SendMsg, NULL);pthread_create(&tid_recv, NULL, RecvMsg, NULL);pthread_join(tid_send, NULL);pthread_join(tid_recv, NULL);close(sockfd);
}

server.c

#include "head.h"int main(void)
{int sockfd = 0;ssize_t nsize = 0;ssize_t size = 0;struct sockaddr_in serveraddr;struct address useraddr[100];struct sockaddr_in userinfo;socklen_t addrlen = 0;addrlen = sizeof(userinfo);struct msgbuf recvuser;int i = 0;sockfd = socket(AF_INET, SOCK_DGRAM, 0);if(sockfd == -1){perror("fail to socket");return -1;}serveraddr.sin_family = AF_INET;serveraddr.sin_port = htons(SERVER_PORT);serveraddr.sin_addr.s_addr = inet_addr(SERVER_ADDR);bind(sockfd, (struct sockaddr *)&serveraddr, sizeof(serveraddr));memset(useraddr, 0, sizeof(useraddr));while(1){memset(&recvuser, 0, sizeof(recvuser));memset(&userinfo, 0, sizeof(userinfo));nsize = recvfrom(sockfd, &recvuser, sizeof(recvuser), 0, (struct sockaddr *)&userinfo, &addrlen);if(nsize == -1){return -1;}if(recvuser.type == USER_TYPE_INT){for(i = 0; i < 100; i++){if(useraddr[i].mark == 1){continue;}else if(useraddr[i].mark == 0){useraddr[i].mark = 1;useraddr[i].cltaddr.sin_family = AF_INET;useraddr[i].cltaddr.sin_port = userinfo.sin_port;useraddr[i].cltaddr.sin_addr.s_addr = userinfo.sin_addr.s_addr;printf("欢迎用户:%s来到直播间!\n", recvuser.name);break;}}}else if(recvuser.type == USER_TYPE_OUT){for(i = 0; i < 100; i++){if(memcmp(&useraddr[i].cltaddr, &userinfo, sizeof(userinfo)) == 0){useraddr[i].mark = 0;printf("用户:%s离开直播间!\n", recvuser.name);}}}else if(recvuser.type == USER_TYPE_CHAT){printf("%s(%s:%d)>%s\n", recvuser.name, inet_ntoa(userinfo.sin_addr), ntohs(userinfo.sin_port), recvuser.text);for(i = 0; i < 100; i++){if(useraddr[i].mark != 0){size = sendto(sockfd, &recvuser, sizeof(recvuser), 0, (struct sockaddr *)&useraddr[i].cltaddr, sizeof(useraddr[i].cltaddr));if(size == -1){perror("fail to sendto");return -1;}}}}}	close(sockfd);return 0;
}

在这里head.h中定义了两个结构体,已经定义了客户发过来的状态

#ifndef _HEAD_H_
#define _HEAD_H_#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <dirent.h>
#include <time.h>
#include <pwd.h>
#include <grp.h>
#include <pthread.h>
#include <semaphore.h>
#include <signal.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/shm.h>
#include <sys/sem.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/inet.h>struct msgbuf
{int type;char name[32];char text[512];
};struct address
{struct sockaddr_in cltaddr;int mark;
};#define USER_TYPE_INT  100
#define USER_TYPE_OUT   200
#define USER_TYPE_CHAT  300#define SERVER_ADDR  "192.168.1.162"
#define SERVER_PORT  5000#endif

相关文章:

嵌入式学习第二十五天!(网络的概念、UDP编程)

网络&#xff1a; 可以用来&#xff1a;数据传输、数据共享 1. 网络协议模型&#xff1a; 1. OSI协议模型&#xff1a; 应用层实际收发的数据表示层发送的数据是否加密会话层是否建立会话连接传输层数据传输的方式&#xff08;数据包&#xff0c;流式&#xff09;网络层数据的…...

实操keepalived(高可用)+Nginx(四层代理+七层代理),实现高可用、负载均衡以及动静分离

一 vrrp技术 VRRP 相关术语 VRRP能够在不改变组网的情况下&#xff0c;将多台路由器虚拟成一个虚拟路由器&#xff0c;i通过配置虚拟路由器的IP地址为默认网关&#xff0c;实现网关的备份。 协议版本: VRRPv2 (常用) 和VRRPv3:0 VRRPv2仅适用于IPv4网络&#xff0c;VRRPv3适用…...

ES6基础3

函数的扩展 基本用法 函数参数的默认值 ES6允许为函数的参数设置默认值&#xff0c;即直接写在参数定义的后面。 参数变量是默认声明的&#xff0c;所以不能用let或const再次声明。下面代码中&#xff0c;参数变量x是默认声明的&#xff0c;在函数体中&#xff0c;不能用let或c…...

HarmonyOS 数据持久化 关系型数据库之 初始化操作

上文 HarmonyOS 数据持久化之首选项 preferences 我们有说用户首选项 但它只能处理一些比较简单的数据类型结构 的持久化处理 如果是一些批量较大 结构较为复杂的数据结构 那么 首选项就无法满足了 我们就要选择 关系型数据库 通过 SQLite 组件实现的一种本地数据库&#xff0…...

伊芙丽签约实在智能,实在Agent数字员工助力品牌效能飙升

近日&#xff0c;国内知名时尚女装品牌伊芙丽与实在智能达成合作&#xff0c;引入业内领先的平台级自动化产品实在Agent数字员工——取数宝&#xff0c;自动获取天猫、淘宝、抖音等线上平台营销数据&#xff0c;开启全域化营销的“提效之旅”。 实在Agent智能体 伊芙丽集团成立…...

第十五届蓝桥杯-UART接收不定长指令的处理

学习初衷&#xff1a; 不仅仅为了比赛&#xff01; 目录 一、问题引入 二、UART常用的三种工作模式 1.UART工作在中断模式 2.UART工作在DMA模式下 3.uart工作在接收转空闲的模式下 三、获取指令中需要的数据 四、printf函数的实现 一、问题引入 问题引入&#xff1a;请…...

网络 协议 UDP编程

网络:数据传输,数据共享 1.网络协议模型: OSI协议模型 应用层 实际发送的数据 表示层 发送的数据是否加密 会话层 是否建立会话连接 传输层 数据传输的方式&#xff08;数据报、流式&#xff09…...

3505. 这也是一道排序题

一、题目 输入 10 7334774857 8461862436 540886577 5245195052 9194400521 5412986878 6694133363 1186771950 1405713915 7115286932 输出 -29430338967 二、思考 构造差分数组&#xff1a;C[i] A[i1] - A[i] 由题目条件可知&#xff1a;当A[i] A[i1] A[i-1] - A[i]时&am…...

【Redis】Redis的应用场景

&#x1f4dd;个人主页&#xff1a;五敷有你 &#x1f525;系列专栏&#xff1a;Redis ⛺️稳中求进&#xff0c;晒太阳 Redis的应用场景&#xff1a; 限流 要求10s内只能访问一次 RequestMapping("xian")public String xianLiu(String sign){String sign1 …...

计算机网络—以太网接口和链路配置

目录 1.拓扑图 2.以太网交换机基础配置 3.配置手动模式的链路聚合 4.配置静态 LACP 模式的链路聚合 5.配置文件 1.拓扑图 2.以太网交换机基础配置 华为交换机接口默认开启了自协商功能&#xff0c;需要手动配置S1与 S2上G0/0/9和G0/0/10接口的速率。 首先修改交换机的设…...

关于做副业、做自媒体:说几句扎心的话

今天在某乎看到一个问题&#xff1a;想尝试自媒体&#xff0c;想了一个月了&#xff0c;都没想好怎么起步&#xff0c;咋整呀&#xff1f; 恰好昨天陪退休老妈去探店&#xff0c;有感而发&#xff0c;就来唠一唠。 一、退休老妈的副业经历 老妈去年年初开始&#xff0c;在某…...

精通SpringBoot单元测试

引言 单元测试是软件开发中不可或缺的一部分&#xff0c;它对保障代码质量和软件的可靠性起着至关重要的作用。而SpringBoot作为一个流行的Java框架&#xff0c;为开发高效、易于部署的微服务提供了强大的支持。 单元测试的重要性&#xff1a; 确保代码正确性&#xff1a;通过…...

HAProxy 简单介绍

一 HAProxy介绍 &#xff08;一&#xff09;发展历史 HAProxy是法国开发者威利塔罗(Willy Tarreau)在2000年使用C语言开发的一个开源软件&#xff0c;是一款具备高并发(一万以上)、高性能的TCP和HTTP负载均衡器&#xff0c;支持基于cookie的持久性&#xff0c;自动故障切换…...

SpringBoot集成Swagger3.0

一&#xff1a;前言   Swagger 是一个 RESTful API 的开源框架&#xff0c;它的主要目的是帮助开发者设计、构建、文档化和测试 Web API。Swagger 的核心思想是通过定义和描述 API 的规范、结构和交互方式&#xff0c;以提高 API 的可读性、可靠性和易用性&#xff0c;同时降…...

计算机网络-第5章 运输层(1)

主要内容&#xff1a;进程之间的通信与端口、UDP协议、TCP协议、可靠传输原理&#xff08;停止等待协议、ARQ协议&#xff09;、TCP报文首部、TCP三大题&#xff1a;滑动窗口、流量控制、拥塞控制机制 5.1 运输层协议概述 运输层向它上面的应用层提供通信服务&#xff0c;真正…...

性能优化-卡牌项目渲染优化

优化的方向 CPU 影响帧率 GPU 影响帧率 内存 超了会崩 显存 显存超了画面会异常&#xff0c;甚至可能导致游戏崩溃 带宽 影响耗电 分辨率 设备性能不行又要求流畅&#xff0c;降低目标渲染分辨率&#xff0c;立竿见影&#xff0c;但是会牺牲画质 场景 1 使用烘焙…...

STM32FreeRTOS任务通知(STM32cube高效开发)

文章目录 一、任务通知(一&#xff09;任务通知概述1、任务通知可模拟队列和信号量2、任务通知优势和局限性 (二) 任务通知函数1、xTaskNotify&#xff08;&#xff09;发送通知值不返回先前通知值的函数2、xTaskNotifyFromISR&#xff08;&#xff09;发送通知函数ISR版本3、x…...

基于element-plus的Dialog选择控件

翻看之前工程师写的vue2的代码&#xff0c;很多都是复制、粘贴&#xff0c;也真是搞不懂&#xff0c;明明可以写一个控件&#xff0c;不就可以重复使用。很多前端总喜欢element搞一下&#xff0c;ant-design也搞一下&#xff0c;有啥意义&#xff0c;控件也不是自己写的&#x…...

手把手教使用静默 搭建Oracle 19c 一主一备ADG集群

一、环境搭建 主机IPora19192.168.134.239ora19std192.168.134.240 1.配置yum源 1.配置网络yum源 1.删除redhat7.0系统自带的yum软件包&#xff1b; rpm -qa|grep yum >oldyum.pkg 备份原信息rpm -qa|grep yum|xargs rpm -e --nodeps 不检查依赖&#xff0c;直接删除…...

使用协程库httpx并发请求

httpx和aiohttp都是比较常用的异步请求库&#xff0c;当然requests多线程或requestsgevent也是不错的选择。 一个使用httpx进行并发请求的脚本如下&#xff1a; import functools import sys import timeimport anyio import httpxasync def fetch(client, results, index) -…...

OFA与LangChain集成:构建智能图文问答系统

OFA与LangChain集成&#xff1a;构建智能图文问答系统 用AI看懂图片并回答你的问题&#xff0c;原来这么简单 你有没有遇到过这样的情况&#xff1a;看到一张复杂的图表&#xff0c;却不知道它在表达什么&#xff1b;或者收到一张产品图片&#xff0c;但找不到相关的说明文档。…...

Qwen3.5-4B-Claude-Opus详细步骤:修改系统提示词打造专属AI助教方法

Qwen3.5-4B-Claude-Opus详细步骤&#xff1a;修改系统提示词打造专属AI助教方法 1. 理解模型特性 1.1 模型基础介绍 Qwen3.5-4B-Claude-4.6-Opus-Reasoning-Distilled-GGUF是一个基于Qwen3.5-4B的推理蒸馏模型&#xff0c;特别强化了结构化分析、分步骤回答、代码与逻辑类问…...

FISCO BCOS 日常操作使用托管签名服务(如WeBASE-Sign),业务系统不直接接触私钥

实战:如何通过WeBASE-Sign实现私钥托管与安全签名 目录 引言 一、为什么需要签名分离 1.1 传统签名的安全困境 1.2 签名分离的架构优势 1.3 适用场景 二、WeBASE-Sign 签名服务核心原理 2.1 整体架构 2.2 核心接口 2.3 交易流程中的签名位置 三、实战:完整接入流程…...

OctoPrintAPI嵌入式库:Arduino/ESP32轻量级REST客户端

1. 项目概述OctoPrintAPI 是一个专为 Arduino 兼容微控制器设计的轻量级 C 库&#xff0c;其核心目标是为嵌入式设备提供稳定、可移植、低侵入性的 OctoPrint REST API 访问能力。该库并非独立服务&#xff0c;而是作为“网络客户端适配层”存在——它不实现 HTTP 协议栈&#…...

OpenCV中的VideoCapture后端参数详解城

智能体时代的代码范式转移与 C# 的战略转型 传统的 C# 开发模式&#xff0c;即所谓的“工程导向型”开发&#xff0c;要求开发者创建一个复杂的项目结构&#xff0c;包括项目文件&#xff08;.csproj&#xff09;、解决方案文件&#xff08;.sln&#xff09;、属性设置以及依赖…...

鸿蒙应用开发实战:5分钟搞定versionCode、versionName等关键信息获取

鸿蒙应用开发实战&#xff1a;5分钟掌握应用关键信息获取技巧 在鸿蒙应用开发过程中&#xff0c;获取应用的版本信息、包名等关键数据是开发者的高频需求。无论是用于版本更新检测、应用内展示&#xff0c;还是配合后端接口校验&#xff0c;这些信息都扮演着重要角色。本文将带…...

算法可视化神器!用动画让冒泡排序、二分查找一目了然

还在为理解冒泡排序的每一趟交换&#xff0c;或是二分查找的边界条件而绞尽脑汁吗&#xff1f;静态的代码和文字描述有时确实不够直观。 想要真正让算法“动”起来&#xff0c;一目了然&#xff1f;强烈推荐你试试**图码这个专注于算法可视化**的神器。 它提供了超过60种数据…...

拆穿名词诈骗!用大白话理解晦涩难懂的AI概念搜

1. 架构背景与演进动力 1.1 从单体到碎片化&#xff1a;.NET 的开源征程 在.NET Framework 时代&#xff0c;构建系统主要围绕 Windows 操作系统紧密集成&#xff0c;采用传统的封闭式开发模式。然而&#xff0c;随着.NET Core 的推出&#xff0c;微软开启了彻底的开源与跨平台…...

揭秘Informer:如何通过ProbSparse注意力机制革新长序列预测

1. 长序列预测的困境与Transformer的瓶颈 想象一下你正在管理一个大型电网系统&#xff0c;需要预测未来30天的电力消耗。面对长达720小时的历史数据&#xff08;每小时一个数据点&#xff09;&#xff0c;传统的LSTM模型在预测超过48小时后的结果就开始出现明显偏差&#xff0…...

三维重建在自动驾驶和数字孪生中的应用实战:聊聊PointNet++与KITTI数据集那些事儿

三维重建在自动驾驶和数字孪生中的应用实战&#xff1a;PointNet与KITTI数据集的深度解析 当激光雷达扫描的数十万个点云数据如暴雨般倾泻而来时&#xff0c;工程师们面临的第一个问题往往是&#xff1a;如何让机器真正"看懂"这些三维空间中的离散信息&#xff1f;这…...