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

UDP通信实现

一、Socket简介(套接字)

        TCP/IP 五层网络模型的应用层编程接口称为Socket API,  Socket( 套接字 ) ,它是对网络中不同主机上的应用进程之间进行双向通信的端点的抽象。 一个套接字就是网络上进程通信的一端,提供了应用层进程利用网络协议交换数据的机制。从所处的地位来讲,套接字上联应用进程,下联网络协议栈是应用程序通过网络协议进行网络通信的接口
Socket 可以看成是两个网络应用程序进行通信时,各自通信连接中的端点,这是一个逻辑上的概
念。
为什么需要Socket
1. 普通的 I/O 操作
        打开文件->读/ 写操作->关闭文件
2. 网络通信
        TCP/IP协议被集成到操作系统的内核中,引入了新型的 “I/O” 操作.
        既然是文件,那么我们可以使用文件描述符引用套接字。与管道类似,Linux 系统将其封装成文件的目的
        是为了统一接口,使得读写套接字和读写文件的操作一致
流式套接字(SOCKET_STREAM)
流式套接 (SOCKET_STREAM):
        提供了一个面向连接、可靠的数据传输服务,数据无差错、无重复的发送且按发送顺序接收。内设置流量控制, 避免数据流淹没慢的接收方。数据被看作是字节流,无长度限制。
数据报套接字 (SOCK_DGRAM):
提供无连接服务。数据包以独立数据包的形式被发送,不提供无差错保证,数据可能丢失或重复,顺序发送,可能乱序接收。
原始套接字 (SOCK_RAW):
可以对较低层次协议如 IP ICMP 直接访问。

二、网络通信

        本质就是:网络通信的本质是不同主机,不同进程之间的通信。

1. 网络通信的核心要素

要素说明
IP地址设备的唯一标识(如IPv4的192.168.1.1,IPv6的2001:db8::1)。
端口号区分同一设备上的不同服务(范围0~65535,如HTTP=80,SSH=22)。
协议规定数据格式和传输规则(如TCP、UDP、HTTP)。
套接字(Socket)编程接口,用于实现网络通信(如Python的socket模块)。

        进程A 需要给进程 B 发送信息,就必须知道进程 B IP+端口号   ,因此每个 Socket 都与端口号和协议有关。

三, UDP通信创建流程

        UDP是一个传输层的无连接的协议,我们编写代码一般是分为两个端,发送端和接收端。正常一般是接收端先运行,然后等待发送端发送数据

1. 流程图

(1) 服务端(接收端)流程

  1. 创建UDP Socket

  2. 绑定IP和端口bind()

  3. 接收数据recvfrom()

  4. 处理数据并响应(可选)

  5. 关闭Socket

(2) 客户端(发送端)流程

  1. 创建UDP Socket

  2. 发送数据sendto()

  3. 接收响应(可选,recvfrom()

  4. 关闭Socket

2、UDP通信相关API函数

1. 创建Socket套接字,实质类似于对文件的操作

#include <sys/types.h> 
#include <sys/socket.h>
函数原型
int socket(int domain, int type, int protocol);
描述
创建一个通信的终端节点,并返回一个指向该端点的文件描述符。
参数
domain:选择用于通信的协议族,目前Linux内核可以理解的格式包括AF_UNIX Local communication(本地通信) AF_LOCAL Synonym for AF_UNIX(AF_UNIX的同义词)AF_INET IPv4 Internet protocols(IPv4互联网协议)......
type:套接字类型,指定通信语义,目前定义的类型有SOCK_STREAM Provides sequenced, reliable, two-way, connection-based byte
streams.SOCK_DGRAM Supports datagrams (connectionless, unreliable messages of a
fixed maximum length)....... 
protocol(/ˈprəʊtəkɒl/协议):协议编号,0表示让系统自动识别

2. 发送数据

头文件
#include <sys/types.h>
#include <sys/socket.h>
函数原型
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:发送的目标地址的大小
返回值
成功:返回发送的字节数
失败:-1并设置errno
【man 7 ip】
struct sockaddr{__SOCKADDR_COMMON (sa_); /* unsigned short int sa_family (协议族) */char sa_data[14]; /* Address data. */};/* Structure describing an Internet socket address. */
struct sockaddr_in{__SOCKADDR_COMMON (sin_);in_port_t sin_port; /* Port number. (端口号字节序) */struct in_addr sin_addr; /* Internet address.(IP网络字节序) *//* 填充到 `struct sockaddr'的大小 */unsigned char sin_zero[sizeof (struct sockaddr)- __SOCKADDR_COMMON_SIZEsizeof (in_port_t)- sizeof (struct in_addr)];};
struct in_addr {in_addr_t s_addr;
};
typedef unsigned short int sa_family_t;
#define __SOCKADDR_COMMON(sa_prefix) \sa_family_t sa_prefix##family
#define __SOCKADDR_COMMON_SIZE (sizeof (unsigned short int))

四, UDP客户端代码实现

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
void send_data(int,struct sockaddr_in*,int);
int main(int argc,char* argv[])
{
if(argc !=3){
fprintf(stderr,"command: %s, ip port\n",argv[0]);
exit(EXIT_FAILURE);}
// 1、创建Socket套接字
int sockfd = socket(AF_INET,SOCK_DGRAM,0);
if(sockfd == -1){
perror("socket");
exit(EXIT_FAILURE);}
// 2、将接收地址的 IP+端口 封装成struct sockaddr_in类型
struct sockaddr_in dest_addr;
dest_addr.sin_family = AF_INET;
dest_addr.sin_port = htons(atoi(argv[2]));
inet_aton(argv[1],&(dest_addr.sin_addr));
// 3、发送数据
send_data(sockfd,&dest_addr,sizeof(dest_addr));
// 4、关闭文件描述符
close(sockfd);
}
void send_data(int sockfd,struct sockaddr_in* pdest_addr,int length)
{
// 循环发送
while(1){
//用户输入发送内容
putchar('>');
char buf[256]={0};
// 清空buf
memset(buf,0,sizeof(buf));
fgets(buf,sizeof(buf),stdin);
// 将回车符转为'\0'
buf[strlen(buf)-1]='\0';
// 发送
int ret = sendto(sockfd,buf,strlen(buf),0,(struct
sockaddr*)pdest_addr,length);
if(ret == -1){
perror("sendto");
exit(EXIT_FAILURE);}
if(strncmp(buf,"quit",4)==0){
break;}}
}

可以使用软件模拟服务器,来判断UDP客户端的代码是否正确

1. 下载
链接: https://pan.baidu.com/s/1-FD4nYgZJlw9nOBrqFm_0A
提取码: 1234

大家可以实现一个小功能;

        编写一个UDP 发送方的代码,新建一个 log.txt 的文件,在文件中写入数据,用户读取 log.txt 文件的内容,通过sendto()发送给网络调试助手,并通过网络测试助手接收数据,判断读取的内容是否正确。

五, UDP服务端代码实现

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <unistd.h>
void receive_message(int sockfd);
int main(int argc,char* argv[])
{
if(argc !=3){
fprintf(stderr,"command:%s ip port\n",argv[0]);
exit(EXIT_FAILURE);}
// 创建socket
int sockfd = socket(AF_INET,SOCK_DGRAM,0);
if(sockfd == -1){
perror("socket");
exit(EXIT_FAILURE);}
// 为socket绑定IP+端口号
struct sockaddr_in addr;
addr.sin_family=AF_INET;
addr.sin_port = htons(atoi(argv[2]));
inet_aton(argv[1],&(addr.sin_addr));
int ret = bind(sockfd,(struct sockaddr*)&addr,(int)sizeof(addr));
if(ret == -1){
perror("bind");
goto release_resources;
exit(EXIT_FAILURE);}
// 接收消息
receive_message(sockfd);
goto release_resources;
return 1;
release_resources:
close(sockfd);
}
void receive_message(int sockfd)
{
char buf[512]={0};
struct sockaddr_in addr;
printf("wait......\n");
while(1){
// 清空
memset(buf,0,sizeof(buf));
socklen_t addrlen = sizeof(addr);
ssize_t bytes = recvfrom(sockfd,buf,sizeof(buf),0,(struct
sockaddr*)&addr,&addrlen);
if(bytes == -1){
perror("recvfrom");}
//打印接收到的消息
printf("src_ip=%s\n",inet_ntoa(addr.sin_addr));
printf("src_port=%d\n",ntohs(addr.sin_port));
printf("content=%s\n",buf);
if(strncmp(buf,"quit",4)==0){
break;}}
}

最终结果;

六, UDP并发服务器之多进程并发

在网络程序里面,通常都是一个服务器处理多个客户端。为了处理多个客户端的请求 , 服务器端程序有不同的处理方式。

1、常见的服务器类型

1.1. 迭代服务器

大多数 UDP 都是迭代运行,服务器等待客户端的数据,收到数据后处理该数据,送回其应答,在等待下一个客户端请求。

1.2. 并发服务器

        并发服务器是指在同一个时刻可以响应多个客户端的请求
        本质是创建多线程/多进程   ,对多数用户的信息进行处理
        UDP协议一般默认是不支持多线程并发的,因为默认UDP服务器只有一个 sockfd ,所有的客户端都是通过同一个sockfd进行通信的,udp使用一个socket,如何做到高并发的呢?

1.3. UDP并发服务器使用的场景

        当UDP协议针对客户请求的处理需要消耗过长的时间时,我们期望 UDP 服务器具有某种形式的并发性。

2、UDP多进程并发服务器

1. 场景设计

        多个udp 客户端需要先验证密钥是否正确后,才允许进行数据交互。假设密钥为 "root" 。(类似于登录功能)
        服务器接收到客户端信息,需要考虑两种情况
                <1>A用户的密钥验证请求消息
                <2>B用户的数据交互接收消息

2. 框架图

所有的客户端都是通过同一个sockfd进行通 信的。udp使用一个 socket ,如何做到做并发呢?

3. 使用场景

        当UDP 服务器与客户端交互多个数据报。问题在于每个客户都是往服务器端的同一个的端口发送数据,并用的同一个sockfd 。并发服务器的每一个子进程如何正确区分每一个客户的数据报(涉及到进程的调度问题,如何避免一个子进程读取到不该它服务的客户发送来的数据报)。
        解决的方法是服务器(知名端口)等待客户的到来,当一个客户到来后,记下其IP port ,然后服务器 fork 一个子进程,建立一个socket bind 一个随机端口,然后建立与客户端的连接,并处理该客户的请求。父进程继续循环,等待下一个客户的到来。

3、代码实现

在tftpd中就是使用这种技术的

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <sys/wait.h>
#include <signal.h>
#define LOGIN_KEY "root"
#define LOGIN_SUCCESS 1
#define LOGIN_FAILURE 0
int init_socket(const char* ip,const char* port)
{
// 创建socket
int sockfd = socket(AF_INET,SOCK_DGRAM,0);
if(sockfd == -1){
perror("socket");
return -1;}
// 绑定IP + 端口
struct sockaddr_in addr;
memset(&addr,0,sizeof(struct sockaddr_in));
addr.sin_family =AF_INET;
addr.sin_port = htons(atoi(port));
inet_aton(ip,&(addr.sin_addr));
int addrlen = sizeof(struct sockaddr_in);
if(bind(sockfd,(struct sockaddr*)&addr,addrlen)==-1){
fprintf(stderr,"bind failed\n");
return -1;}
return sockfd;
}
int authentication_key(const char* ip,const char* port)
{
int sockfd = init_socket(ip,port);
if(sockfd == -1){
return -1;}
char buf[512]={0};
int len = sizeof(buf);
struct sockaddr_in addr;
int addrlen = sizeof(addr);
int new_sockfd;
// 循环验证用户密钥
while(1){
memset(buf,0,len);
ssize_t recvbytes = recvfrom(sockfd,buf,len,0,(struct
sockaddr*)&addr,&addrlen);
if(recvbytes == -1){
perror("redvfrom");
return -1;}
unsigned char loginstatus = (strncmp(buf,LOGIN_KEY,4)==0)?
LOGIN_SUCCESS:LOGIN_FAILURE;
if(loginstatus == LOGIN_SUCCESS){
pid_t pid = fork();
if(pid == -1){
perror("fork");
return -1;}
else if(pid == 0){
// 执行的是子进程
close(sockfd);//密钥验证成功,不需要sockfd文件描述符
new_sockfd = init_socket(ip,"0");// 绑定0端口,系统
会随机分配一个可用的端口号
sendto(new_sockfd,&loginstatus,sizeof(loginstatus),0,(struct
sockaddr*)&addr,addrlen);
break;}}
else{
// 登录失败,使用原端口回复信息
ssize_t ret =
sendto(sockfd,&loginstatus,sizeof(loginstatus),0,(struct sockaddr*)&addr,addrlen);}}
return new_sockfd;
}
// 接收数据
void recv_data(int sockfd)
{
char buf[512]={0};
struct sockaddr_in client_addr;
socklen_t addrlen = sizeof(client_addr);
while(1){
memset(buf,0,sizeof(buf));
ssize_t recvbytes = recvfrom(sockfd,buf,sizeof(buf),0,(struct
sockaddr*)&client_addr,&addrlen);
if(recvbytes== -1){
perror("recvfrom");
exit(EXIT_FAILURE);}
printf("client ip:%s\n",inet_ntoa(client_addr.sin_addr));
printf("client port:%d\n",ntohs(client_addr.sin_port));
printf("client content:%s\n",buf);
if(strncmp(buf,"quit",4)==0){
break;}}
close(sockfd);
exit(EXIT_SUCCESS);
}
void signal_handler(int signum)
{
// 回收子进程的资源
waitpid(-1,NULL,WNOHANG);
printf("%s\n",strsignal(signum));
}
int main(int argc,char* argv[])
{
if(argc !=3){
fprintf(stderr,"%s ip port.\n",argv[0]);
exit(EXIT_FAILURE);}
// 回收僵尸态的子进程[子进程结束后,会发SIGCHLD信号]
if(signal(SIGCHLD,signal_handler)==SIG_ERR){
perror("signal error.");
exit(EXIT_FAILURE);}
// 验证秘钥
int sockfd = authentication_key(argv[1],argv[2]);
// recv data
recv_data(sockfd);
return 0;
}

客户端不需要进行修改,如此就实现了客户端和服务处理高并发的基础功能

结果:

相关文章:

UDP通信实现

一、Socket简介&#xff08;套接字) TCP/IP 五层网络模型的应用层编程接口称为Socket API, Socket( 套接字 ) &#xff0c;它是对网络中不同主机上的应用进程之间进行双向通信的端点的抽象。 一个套接字就是网络上进程通信的一端&#xff0c;提供了应用层进程利用网络协议交换…...

Browserlist 使用指南:应对浏览器兼容性问题的解决方案

前言 在前端开发中&#xff0c;我们经常需要处理各种不同的浏览器兼容性问题。每个浏览器的版本众多&#xff0c;处理这些问题可能会让人感到头疼。幸运的是&#xff0c;有一个名为 Browserlist 的工具可以大大简化这项工作。本文将介绍 Browserlist 的作用和使用方法&#xf…...

[蓝桥杯 2023 省 A] 异或和之和

题目来自洛谷网站&#xff1a; 暴力思路&#xff1a; 先进性预处理&#xff0c;找到每个点位置的前缀异或和&#xff0c;在枚举区间。 暴力代码&#xff1a; #include<bits/stdc.h> #define int long long using namespace std; const int N 1e520;int n; int arr[N…...

ABC391题解

A 算法标签: 模拟 #include <iostream> #include <algorithm> #include <cstring> #include <map>using namespace std;const int N 8; map<string, string> mp;int main() {ios::sync_with_stdio(false);cin.tie(0), cout.tie(0);mp.insert({…...

React - LineChart组件编写(用于查看每日流水图表)

一、简单版本 LineChart.tsx // src/component/LineChart/LineChart.tsx import React, {useEffect,useRef,useImperativeHandle,forwardRef,useMemo,useCallback, } from react; import * as echarts from echarts/core; import type { ComposeOption } from echarts/core; …...

什么情况下需要使用二级指针

当你需要一个函数修改另一个函数中的指针变量时&#xff08;改变指针变量的指向&#xff09;&#xff0c;你必须传递该指针的地址&#xff0c;也就是"指向指针的指针"。这是C语言中实现"引用传递"效果的标准方式。 函数A中声明了一个结构体指针变量mys&am…...

动态规划(8.下降路径最小和(medium))

题目链接&#xff1a;931. 下降路径最小和 - 力扣&#xff08;LeetCode&#xff09; 解法&#xff1a; 关于这⼀类题&#xff0c;由于我们做过类似的&#xff0c;因此「状态表示」以及「状态转移」是比较容易分析出来的。 比较难的地方可能就是对于「边界条件」的处理。 1. 状…...

自动插入分号机制

&#x1f4dc; JS 自动分号插入(ASI)机制详解 自动分号插入(Automatic Semicolon Insertion)是 JavaScript 中一个独特而重要的特性&#xff0c;它影响着代码的解析和执行方式。 &#x1f31f; 核心概念速览 ASI 引擎自动补充分号 当 JavaScript 解析器遇到特定语法情况时&a…...

C语言贪吃蛇实现

When the night gets dark,remember that the Sun is also a star. 当夜幕降临时&#xff0c;请记住太阳也是一颗星星。 ————《去月球海滩篇》 目录 文章目录 一、《贪吃蛇》游戏介绍 二、WIN32部分接口简单介绍 2.1 控制台窗口大小设置 2.2 命令行窗口的名称的变更 2…...

基于数据挖掘的网络入侵检测关键技术研究

标题:基于数据挖掘的网络入侵检测关键技术研究 内容:1.摘要 随着互联网的迅速发展&#xff0c;网络安全问题日益严峻&#xff0c;网络入侵行为对个人、企业和国家的信息安全构成了巨大威胁。本文的目的是研究基于数据挖掘的网络入侵检测关键技术&#xff0c;以提高网络入侵检测…...

git上传大文件到远程仓库中

git 上传大文件报错 上传大文件文件到远程仓库上面&#xff0c;出现错误&#xff08;gitee-100M,github-50M&#xff09; remote: error: File: f422c55c723a183a1944cbec840c0171042c8251 135 MB, exceeds 100.00 MB. 意思是单个文件超过100M导致上传失败。 安装LFS curl…...

计算机网络基础之三种交换技术及其性能分析

一. 交换技术基础 1. 三种交换技术 电路交换&#xff1a;用于电话网络报文交换&#xff1a;用于电报网络分组交换&#xff1a;用于现代计算机网络 2. 人类历史上的通信网络 #mermaid-svg-AeGvrkUbCkicFOIo {font-family:"trebuchet ms",verdana,arial,sans-serif;…...

ANYmal Parkour: Learning Agile Navigation for Quadrupedal Robots

ANYmal Parkour: Learning Agile Navigation for Quadrupedal Robots 研究动机解决方案技术路线感知模块运动模块导航模块补充 实验结果 ANYmal Parkour: Learning Agile Navigation for Quadrupedal Robots 研究动机 行走控制器不能依赖于稳定和周期性的步态&#xff0c;而必…...

【AI学习笔记】AI造神时代的潘式理论与智能进化

背景前摇&#xff1a; 周会分享选题&#xff0c;决定选择这篇华为蓝军部长潘少钦先生所著的文章&#xff0c;原题目为《AI如此强大&#xff0c;我是否要改行&#xff1f;》。选择这篇文章的理由是&#xff0c;其不仅有充实扎实的AI基础知识作为铺垫&#xff0c;更具有独特鲜明…...

CVE-2021-45232未授权接口练习笔记

CVE-2021-45232 是 Apache APISIX Dashboard 中的一个严重权限漏洞&#xff0c;类似于攻击者无需密码即可拿到整个网关系统的“万能钥匙”。攻击者利用此漏洞&#xff0c;可直接操控网关流量转发规则&#xff0c;甚至远程执行代码&#xff0c;引发服务器沦陷。 默认账户密码导致…...

远场分量(平面波角谱)与倏逝波

远场分量&#xff08;平面波角谱&#xff09;与倏逝波的详细解释 在光学和电磁学中&#xff0c;远场分量&#xff08;平面波角谱&#xff09;和倏逝波是描述光场传播特性的两个核心概念&#xff0c;尤其在衍射理论、近场光学和超分辨成像中至关重要。以下是它们的物理意义、数…...

修改Flutter工程中Android项目minSdkVersion配置

Flutter项目开发过程中&#xff0c;根据模板自动生成.android项目&#xff0c;其中app>build.gradle中minSdkVersion的值是19&#xff0c;但是依赖了一个三方库&#xff0c;它的Android sdk 最小版本只支持到21&#xff0c;运行报错如下&#xff1a; 我们可以手动修改.andro…...

后端返回了 xlsx 文件流,前端怎么下载处理

当后端返回一个 .xlsx 文件流时&#xff0c;前端可以通过 JavaScript 处理这个文件流并触发浏览器下载。 实现步骤 发送请求获取文件流&#xff1a; 使用 fetch 或 axios 等工具向后端发送请求&#xff0c;确保响应类型设置为 blob&#xff08;二进制数据流&#xff09;。 创建…...

js中async+await+promise的用法及常见问题总结

文章目录 概况asyncawaitPromise总结常见问题 概况 在ts/js中&#xff0c;async 和 await 是用于简化异步操作的关键字&#xff0c;一般与Promise联用&#xff08;不理解Promise可以看一下这篇《JS中Promise用法&#xff08;简要说明&#xff09;》&#xff09;。它们的核心作…...

单纯形法之大M法

1. 问题背景与标准化 在求解某些线性规划问题时&#xff0c;往往难以直接找到初始的基本可行解。特别是当约束中存在等式或 “≥” 类型的不等式时&#xff0c;我们需要引入人工变量来构造一个初始可行解。 考虑如下标准形式问题&#xff08;假设为最大化问题&#xff09;&am…...

一个数组分为两个sum相等的数组

vector&#xff0c;问是否可以拆成两部分&#xff0c;使其两部分的总和相同&#xff0c;用代码写一下 #include <iostream> #include <vector>using namespace std;bool canPartition(vector<int>& nums) {int sum 0;for (int num : nums) {sum num;…...

Socket如何实现客户端和服务器间的通信

使用Socket实现客户端和服务器间的通信 Socket是一种网络编程接口&#xff0c;广泛用于实现客户端和服务器之间的通信。在网络应用程序中&#xff0c;Socket提供了一种简单而强大的机制来建立和管理网络连接。本文将详细介绍如何使用Python的Socket模块来实现基本的客户端和服…...

崖山数据库(YashanDB)部署全流程详解

文章目录 引言 第1部分&#xff1a;环境准备 服务器要求 初始环境调整 第2部分&#xff1a;yasboot工具介绍 yasboot核心功能 yasboot进程架构 第3部分&#xff1a;YashanDB安装步骤 创建安装用户 目录规划 命令行安装流程 步骤1&#xff1a;生成配置文件 步骤2&a…...

07_JavaScript函数作用域_递归

目录 一、作用域&#xff08;重点&#xff09; 二、变量的使用规则 &#xff08;重点&#xff09; 2.1 访问规则 2.2 赋值规则 三、递归函数 &#xff08;难点&#xff09; 了解 四、对象 4.1 对象的创建 一、作用域&#xff08;重点&#xff09; 什么是作用域 ? 作用…...

基于大模型预测的初治菌阳肺结核诊疗方案研究报告

目录 一、引言 1.1 研究背景与意义 1.2 研究目的 二、初治菌阳肺结核概述 2.1 疾病定义与病理机制 2.2 流行病学特征 2.3 传统诊疗方法与局限性 三、大模型在初治菌阳肺结核预测中的应用原理 3.1 大模型技术简介 3.2 数据收集与预处理 3.3 模型构建与训练 3.4 模型…...

C# Modbus TCP/IP学习记录

Modbus协议中&#xff0c;角色分为主站&#xff08;Mater&#xff09;、从站&#xff08;Slave&#xff09;&#xff1b;数据类型分为线圈&#xff08;Coil&#xff09;、离散输入&#xff08;Input&#xff09;、保持寄存器&#xff08;HoldingRegister&#xff09;、输入寄存…...

斜线、短横、空格,三种分隔日期的优雅解析(Python | DeepSeek)

标准日期解析操作&#xff0c;str.replace链式如灵蛇蜿蜒&#xff0c;三元表达式像空灵仙家妙法。 笔记模板由python脚本于2025-03-25 22:32:24创建&#xff0c;本篇笔记适合三元表达式、字符串操作修习的coder翻阅。 【学习的细节是欢悦的历程】 博客的核心价值&#xff1a;在…...

Skynet 中 snlua 服务启动整体流程分析

前言&#xff1a; 在 Skynet 中&#xff0c;Lua 扮演了极其重要的角色。Skynet 大多数业务逻辑都跑在一个个 Lua 服务里&#xff0c;而能够将 Lua 环境嵌入到 Skynet 框架下&#xff0c;并与 Skynet 消息调度机制完美结合&#xff0c;正是 snlua 服务所承担的核心功能。 本文将…...

RWA代币化崛起中的香港机遇:数字金融新枢纽的破局之道

引言&#xff1a;全球资产代币化浪潮中的香港坐标 在2025年全球金融数字化重构的关键节点&#xff0c;RWA&#xff08;现实世界资产代币化&#xff09;市场以年均740%的增速重塑价值流动规则。香港凭借独特的政策创新、跨境枢纽优势及庞大的资产储备&#xff0c;正从传统金融中…...

Docker Compose介绍

基本概念 Docker-Compose是Docker官方的开源项目&#xff0c;负责实现对docker容器集群的快速编排。 可以这么理解&#xff0c;docker compose是docker提出的一个工具软件&#xff0c;可以管理多个docker容器组成一个应用&#xff0c;只需要编写一个YAML格式的配置文件docker…...

【LeetCode 题解】算法:15.三数之和

一、问题描述 在 LeetCode 上有这样一道经典的算法题&#xff0c;题目要求给定一个整数数组 nums&#xff0c;找出所有不重复的三元组 [nums[i], nums[j], nums[k]]&#xff0c;需要满足以下两个条件&#xff1a; 三个元素的索引互不相同&#xff0c;即 i ! j&#xff0c;i ! …...

springboot使用阿里限流框架-sentinel

当前项目源码 控制台下载 启动bin中的看板服务&#xff1a;账号密码:sentinel/sentinel 官方文档地址 项目引入依赖 <!-- sentinel注解支持 --> <dependency><groupId>com.alibaba.csp</groupId><artifactId>sentinel-annotation-aspectj<…...

Ubuntu20.04系统安装IsaacSim4.5与IsaacLab环境

Introduction 今天用自己的Ubuntu20.04系统安装最新更新的IsaacSim 4.5 与 最新版的IsaacLab遇到了问题&#xff0c;且这个问题组里师兄之前也遇到了&#xff0c;我的解决方法是从头来过&#xff0c;所及记录一下。 IsaacSim现在支持pip安装&#xff0c;但是Ubuntu20.04的pip…...

【大模型】数字人 EchoMimicV2 的环境配置和使用

一、EchoMimicV2的简单介绍 EchoMimicV2是EchoMimicV1的升级版本&#xff0c;旨在通过音频驱动生成更加自然和流畅的半身人类动画。它能够让用户仅通过简单的音频输入&#xff0c;生成与声音内容相匹配的动画效果&#xff0c;使虚拟人物看起来更加生动。 作者&#xff1a;由蚂蚁…...

导入 Excel 规则批量修改或删除 PDF 文档内容

需要对 PDF 文档内容进行修改的时候&#xff0c;通常我们会需要借助一些专业的工具来帮我们完成。那我们如果需要修改的 PDF 文档较多的时候&#xff0c;有什么方法可以帮我们实现批量操作呢&#xff1f;今天这篇文章就给大家介绍一下当我们需要批量修改多个 PDF 文档的时候&am…...

2.Excel :快速填充和拆分重组

一 案例1&#xff1a;快速填充 电子邮件中包含每个人的人名&#xff0c;现在要提取电子邮件中的姓名到名字列。 方法1&#xff1a;将 Nancy 复制到单元格后&#xff0c;邮件会高亮&#xff0c;然后输入A的时候系统就会知道提取名字了。 补充&#xff1a;如果第三个位置输入错误…...

python tkinter 开发蓍草占卜系统

1. 项目概述 1.1 简介 蓍草占卜是中国传统的占卜方法&#xff0c;用于演算六十四卦。本系统通过现代编程技术&#xff0c;将传统的蓍草占卜方法数字化&#xff0c;提供一个准确、便捷的占卜工具。 蓍草占卜&#xff0c;作为中国古代的一种传统占卜方法&#xff0c;承载着深厚…...

综合小实验之电视机

综合小实验1 一、实验拓扑图 二、实验要求 按照图示配置IP地址&#xff1b;按照图示区域划分配置对应的动态路由协议&#xff1b;在R7上配置dhcp服务器&#xff0c;能够让pc可以获取IP地址&#xff1b;将所有环回⼝宣告进ospf中&#xff0c;将环回⼝7宣告进rip中&#xff0c;…...

全排列|| 分发饼干 摆动序列

1.给定一个可包含重复数字的序列 nums &#xff0c;按任意顺序 返回所有不重复的全排列。 示例 1&#xff1a; 输入&#xff1a;nums [1,1,2] 输出&#xff1a; [[1,1,2], [1,2,1], [2,1,1]] 示例 2&#xff1a; 输入&#xff1a;nums [1,2,3] 输出&#xff1a;[[1,2,3…...

【开源宝藏】用 JavaScript 手写一个丝滑的打字机动画效果

你当前项目实现了一个非常丝滑的 打字机文字效果动画&#xff0c;使用的是自定义的 typical.js 脚本。下面我将给出一份逐步拆解的中文教程&#xff0c;帮你或其他初学者快速上手并自定义这个打字效果。 ✨ 最终效果 打开页面后&#xff0c;中央会逐字显示&#xff1a; Hello…...

推荐1款简洁、小巧的实用收音机软件,支持手机和电脑

聊一聊 没想到现在还有人喜欢听广播。 我一直以为听广播必须要用那种小广播机才可以。 原来手机或电脑上也是可以的。 今天给大家分享一款可以在电脑和手机上听广播的软件。 软件介绍 龙卷风收音机 电台广播收音机分电脑和手机两个版本。 电脑端无需安装&#xff0c;下载…...

64. MfgTool烧写工具详解

一、MfgTool工具简介 1、mfgtool是NXP官方做的向I.MX系列烧写系统的软件&#xff0c;运行在windows下。可以烧写uboot.imx、zImage、dtb&#xff0c;rootfs。通过USB烧写。 Mfgtool里面默认存放了NXP官方开发板的系统文件&#xff0c; 2、基本原理 向开发板烧系统分两部分&am…...

3、孪生网络/连体网络(Siamese Network)

目的: 用Siamese Network (孪生网络) 解决Few-shot learning (小样本学习)。 Siamese Network并不是Meta Learning最好的方法, 但是通过学习Siamese Network,非常有助于理解其他Meta Learning算法。 这里介绍了两种方法:Siamese Network (孪生网络)、Trplet Loss Siam…...

前端学习笔记--CSS

HTMLCSSJavaScript 》 结构 表现 交互 如何学习 1.CSS是什么 2.CSS怎么用&#xff1f; 3.CSS选择器&#xff08;重点&#xff0c;难点&#xff09; 4.美化网页&#xff08;文字&#xff0c;阴影&#xff0c;超链接&#xff0c;列表&#xff0c;渐变。。。&#xff09; 5…...

开个坑记录一下树莓派4B部署yolo的一些问题

问题一&#xff1a;操作系统与内核信息 这个问题困扰了我一天半&#xff0c;下载的时候显示的信息是aar64的系统&#xff0c;但是这并无意味着一个问题&#xff0c;那就是你的操作系统是64位的。需要采用如下的指令查看&#xff1a; getconf LONG_BIT 我在树莓派得出来的操作…...

1.1 结构体与类对象在List中使用区别

一、问题的起源如下的代码是错误的&#xff0c;无法编译通过 struct Point {public int X;public int Y; }List<Point> points new List<Point> { new Point { X 1, Y 2 } }; points[0].X 10; // 编译错误&#xff01;无法修改副本的字段 二、原因分析 在C#中&…...

详细说明windows系统函数::SetUnhandledExceptionFilter(ExceptionFilter)

::SetUnhandledExceptionFilter(ExceptionFilter); 是 Windows 编程中用于设置顶层未处理异常过滤器的关键 API 调用。它属于 Windows 结构化异常处理&#xff08;SEH, Structured Exception Handling&#xff09;机制的一部分&#xff0c;主要用于捕获那些未被程序内部处理的异…...

力扣刷题39. 组合总和

39. 组合总和 - 力扣&#xff08;LeetCode&#xff09; 需要定义一个index变量用来记录访问数组的下标&#xff0c;每次递归进行传参&#xff0c;在搜索过程中&#xff0c;因为为了避免重复数据&#xff0c;而且允许一个元素的重复出现&#xff0c;传入index时传入当前遍历的i…...

正弦函数的连续傅里叶变换正弦序列的DTFT

正弦序列 时域 x [ n ] sin ⁡ ( ω 0 n ) x[n] \sin(\omega_0 n) x[n]sin(ω0​n)频域 X ( e j ω ) j π 2 [ δ ( ω − ω 0 ) − δ ( ω ω 0 ) ] X({\rm e}^{{\rm j}\omega}) \frac{{\rm j}\pi}{2} \left[ \delta(\omega - \omega_0) - \delta(\omega \omega_0…...

winstart.wsf 病毒清理大作战

0x00 背景 发现感染了winstart.wsf 病毒如何清理。 0x01 现象 遍历Users下每个目录以及C:\和C:\Windows\Temp 2个目录写入病毒文件。 C:\Users\Administrator\AppData\Local\Temp\winstart.wsf C:\Users\Administrator\AppData\Roaming\Microsoft\Windows\Start Menu\Program…...