嵌入式学习——网络编程(TCP)——day31
1. TCP和UDP的区别
TCP(Transmission Control Protocol,传输控制协议)
UDP(User Datagram Protocol,用户数据报协议)
1.1 连接方式
- TCP 是面向连接的协议,它在数据传输前需要通过三次握手建立一个可靠的连接,确保双方都准备好进行通信,并维护连接状态直到连接被明确关闭(四次挥手)。
- UDP 是无连接的协议,它不建立正式的连接就可以直接发送数据包。发送端和接收端之间没有事先的握手过程,每个数据报都是独立发送的。
1.2 可靠性
- TCP 提供可靠的数据传输服务,确保数据包按序、无损地到达接收端。它通过序列号、确认应答、错误检测、重传机制和流量控制来保证数据的可靠性和顺序。
- UDP 不提供这些保障,数据包可能丢失、重复或乱序到达,适用于对实时性要求高于数据完整性的应用。
1.3 速度与效率
- TCP 因其额外的控制信息和确认过程,相比UDP来说,传输效率较低,但提供了更高的可靠性。
- UDP 由于其简单、无连接的特性,传输速度快,延迟低,适合实时应用。
1.4 数据包处理
- TCP 将数据视为字节流,可以拆分和重组数据包,适合传输大量或连续的数据。
- UDP 保留了数据报的边界,作为独立的数据单元传输,适合一次性传输小块或具有明确界限的数据。
1.5 应用场景
- TCP 适用于需要高度可靠传输的应用,如Web浏览、电子邮件、文件传输(FTP)等。
- UDP 适用于实时性要求高、可以容忍一定数据丢失的应用,如在线游戏、语音通话、视频流、DNS查询等。
1.6 资源消耗与复杂性
- TCP 需要更多的系统资源来维护连接状态和执行复杂的错误恢复机制。
- UDP 相对轻量,对系统资源的需求较少,程序实现也更为简单
2. TCP接口函数
2.1 socket
socket(AF_INET, SOCK_STREAM, 0);
2.2 connect
int connect(int sockfd, const struct sockaddr *addr,
socklen_t addrlen);
功能:
向接收端发送三次握手链接请求
参数:
sockfd:文件描述符
addr:接收方地址空间首地址
addrlen:接收方地址的大小
返回值:
成功返回0
失败返回-1
2.3 send (发的太块会阻塞)
ssize_t send(int sockfd, const void *buf, size_t len, int flags);
功能:
发送数据
参数:
sockfd:文件描述符
buf:存放数据空间首地址
len:发送数据长度
flags:属性 默认为0
返回值:
成功返回发送字节数
失败返回-1
2.4 recv
ssize_t recv(int sockfd, void *buf, size_t len, int flags);
功能:
接收数据
参数:
sockfd:文件描述符
buf:存放数据空间首地址
len:最多接收数据大小
flags:属性 默认为0
返回值:
成功返回实际接收字节数
失败返回-1
对方关闭套接字返回0
2.5 listen
int listen(int sockfd, int backlog);
功能:
监听链接请求
参数:
sockfd:文件描述符
backlog:允许最多等待链接的个数
返回值:
成功返回0
失败返回-1
2.6 accept(返回通信套接字)
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
功能:
处理等待队列中第一个链接
参数:
sockfd:文件描述符
addr:存放链接对方地址信息空间首地址
addrlen:想要接收地址大小变量空间首地址
返回值:
成功返回与发送端建立的新文件描述符(通信套接字)
失败返回-1
2.7 inet_addr
in_addr_t inet_addr(const char *cp);
功能:
将字符串IP地址转换为二进制IP地址
参数:
cp:字符串IP地址空间首地址
返回值:
成功返回二进制IP地址
2.8 htons
uint16_t htons(uint16_t hostshort);
功能:
将本地字节序(小端)转换为网络字节序(大端)
参数:
hostshort:本地端口号
返回值:
返回网络字节序端口号
uint16_t ntohs(uint16_t netshort);
功能:
将网络字节序(大端)转换为本地字节序(小端)
2.9 bind
int bind(int sockfd, const struct sockaddr *addr,
socklen_t addrlen);
功能:
将套接字与IP地址端口绑定在一起
参数:
sockfd:文件描述符
addr:结构体空间首地址
addrlen:信息的长度
返回值:
成功返回0
失败返回-1
2.10 示例程序
(1)TCP单向通信
1. 头文件
#ifndef _HEAD_H_
#define _HEAD_H_#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <time.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <pthread.h>#endif
2. makefile
all:send recvsend:send.cgcc $^ -o $@
recv:recv.cgcc $^ -o $@
3. recv.c
#include "head.h"int main(int argc, char const *argv[])
{int confd = 0;int listfd = 0;int ret_connect = 0;int ret_bind = 0;int ret_listen = 0;struct sockaddr_in recvaddr;struct sockaddr_in sendaddr;socklen_t addrlen = sizeof(sendaddr);ssize_t ret_send = 0;ssize_t ret_recv = 0;listfd = socket(AF_INET, SOCK_STREAM, 0);if (-1 == listfd){perror("socket error!\n");return -1;}bzero(&recvaddr,sizeof(recvaddr));bzero(&sendaddr,sizeof(sendaddr));recvaddr.sin_family = AF_INET;recvaddr.sin_port = htons(50000);recvaddr.sin_addr.s_addr = inet_addr("192.168.0.109");ret_bind = bind(listfd, (struct sockaddr *)&recvaddr, sizeof(recvaddr));if (-1 == ret_bind){perror("bind error!\n");return -1;}ret_listen = listen(listfd, 3);if (-1 == ret_listen){perror("listen error!\n");return -1; }confd = accept(listfd, (struct sockaddr *)&sendaddr, &addrlen);if (-1 == confd){perror("accept error!\n");return -1; }while (1){char buf[256] = {0};ret_recv = recv(confd, buf, sizeof(buf), 0);if (ret_recv <= 0){break;}time_t tm;time(&tm);sprintf(buf, "%s %s", buf, ctime(&tm));ret_send = send(confd, buf, strlen(buf), 0);if (-1 == ret_send){perror("send error!\n");return -1; } }close(confd);close(listfd);return 0;
}
4. send.c
#include "head.h"int main(int argc, char const *argv[])
{int confd = 0;int ret_connect = 0;struct sockaddr_in recvaddr;socklen_t addrlen = 0;ssize_t ret_send = 0;ssize_t ret_recv = 0;confd = socket(AF_INET, SOCK_STREAM, 0);if (-1 == confd){perror("socket error!\n");return -1;}bzero(&recvaddr, sizeof(recvaddr));recvaddr.sin_family = AF_INET;recvaddr.sin_port = htons(50000);recvaddr.sin_addr.s_addr = inet_addr("192.168.0.109");ret_connect = connect(confd, (struct sockaddr *)&recvaddr, sizeof(recvaddr));if (-1 == ret_connect){perror("connect error!\n");return -1; }while (1){char buf[256] = {"supercarrydoinb"};ret_send = send(confd, buf, strlen(buf), 0);if (-1 == ret_connect){perror("send error!\n");return -1; } ret_recv = recv(confd, buf, sizeof(buf), 0);if (ret_recv <= 0){break;}printf("%s", buf);sleep(1);}close(confd);return 0;
}
(2) TCP实现多线程双机聊天(chat)——注意:!!线程编译gcc要加后缀 -lpthread
1. 头文件
#ifndef _HEAD_H_
#define _HEAD_H_#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <time.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <pthread.h>#endif
2. makefile
all:send recvsend:send.cgcc $^ -o $@ -lpthread
recv:recv.cgcc $^ -o $@ -lpthread
3. send.c
#include "head.h"struct sockaddr_in sendaddr;
struct sockaddr_in recvaddr;void *th1(void *arg)
{int confd = *(int *)arg;ssize_t ret_recv = 0;while (1){char buf[256] = {0};ret_recv = recv(confd, buf, sizeof(buf), 0);if (-1 == ret_recv){perror("recv error!\n");}printf("from recv: %s\n", buf);}
}void *th2(void *arg)
{int confd = *(int *)arg;ssize_t ret_send = 0;while (1){printf("to recv:");char buf[256] = {0};fgets(buf, sizeof(buf), stdin);buf[strlen(buf)-1] = '\0';ret_send= send(confd, buf, strlen(buf), 0);if (-1 == ret_send){perror("send error!\n");}}
}int main(int argc, char const *argv[])
{int confd = 0;int ret_connect = 0;socklen_t addrlen = sizeof(sendaddr);ssize_t ret_recv = 0;ssize_t ret_send = 0;pthread_t tid1;pthread_t tid2;char buf[256] = {0};confd = socket(AF_INET, SOCK_STREAM, 0);if (-1 == confd){perror("socket error!\n");return -1;}bzero(&recvaddr, sizeof(recvaddr));bzero(&sendaddr, sizeof(sendaddr));recvaddr.sin_family = AF_INET;recvaddr.sin_port = htons(50000);recvaddr.sin_addr.s_addr = inet_addr("192.168.0.109");ret_connect = connect(confd, (struct sockaddr *)&recvaddr, sizeof(recvaddr));if (-1 == ret_connect){perror("connect error!\n");return -1;}#if 0ret_recv = recv(confd, buf, sizeof(buf), 0);if (-1 == ret_recv){perror("recv error!\n");return -1;}
#endifpthread_create(&tid1, NULL, th1, &confd);pthread_create(&tid2, NULL, th2, &confd);pthread_join(tid1, NULL);pthread_join(tid1, NULL);return 0;
}
4. recv.c
#include "head.h"struct sockaddr_in sendaddr;
struct sockaddr_in recvaddr;void *th1(void *arg)
{int confd = *(int *)arg;ssize_t ret_recv = 0;while (1){char buf[256] = {0};ret_recv = recv(confd, buf, sizeof(buf), 0);if (-1 == ret_recv){perror("recv error!\n");}printf("from send: %s\n", buf);}
}void *th2(void *arg)
{int confd = *(int *)arg;ssize_t ret_send = 0;while (1){printf("to send:");char buf[256] = {0};fgets(buf, sizeof(buf), stdin);buf[strlen(buf)-1] = '\0';ret_send = send(confd, buf, strlen(buf), 0);if (-1 == ret_send){perror("send error!\n");}}
}int main(int argc, char const *argv[])
{int listfd = 0;int confd = 0;int ret_bind = 0;int ret_listen = 0;socklen_t addrlen = sizeof(sendaddr);ssize_t ret_recv = 0;ssize_t ret_send = 0;pthread_t tid1;pthread_t tid2;char buf[256] = {0};listfd = socket(AF_INET, SOCK_STREAM, 0);if (-1 == listfd){perror("socket error!\n");return -1;}bzero(&recvaddr, sizeof(recvaddr));bzero(&sendaddr, sizeof(sendaddr));recvaddr.sin_family = AF_INET;recvaddr.sin_port = htons(50000);recvaddr.sin_addr.s_addr = inet_addr("192.168.0.109");ret_bind = bind(listfd, (struct sockaddr *)&recvaddr, sizeof(recvaddr));if (-1 == ret_bind){perror("bind error!\n");return -1;}ret_listen = listen(listfd, 3);if (-1 == ret_listen){perror("listen error!\n");return -1; }confd = accept(listfd, (struct sockaddr *)&sendaddr, &addrlen);if (-1 == confd){perror("accept error!\n");return -1; }#if 0ret_recv = recv(confd, buf, sizeof(buf), 0);if (-1 == ret_recv){perror("recv error!\n");return -1;}
#endifpthread_create(&tid1, NULL, th1, &confd);pthread_create(&tid2, NULL, th2, &confd);pthread_join(tid1, NULL);pthread_join(tid1, NULL);return 0;
}
(3) TCP实现文件的传输(结构体)
1. 头文件
#ifndef _HEAD_H_
#define _HEAD_H_#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <time.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <pthread.h>#endif
2. makefile
all:send recvsend:send.cgcc $^ -o $@ -lpthread
recv:recv.cgcc $^ -o $@ -lpthread
3. send.c
#include "head.h"typedef struct
{char buf[1024];char filename[32];int rd_ret;int total;
}MSG;int main(int argc, char const *argv[])
{int ret_connect = 0;int ret_stat = 0;int confd = 0;int openfd = 0;ssize_t ret_recv = 0;ssize_t ret_send = 0;struct sockaddr_in recvaddr;MSG msg;struct stat st;confd = socket(AF_INET, SOCK_STREAM, 0);if (-1 == confd){perror("socket error!\n");return -1;}bzero(&recvaddr, sizeof(recvaddr));bzero(&msg, sizeof(msg));recvaddr.sin_family = AF_INET;recvaddr.sin_port = htons(50000);recvaddr.sin_addr.s_addr = inet_addr("192.168.0.109");ret_connect = connect(confd, (struct sockaddr *)&recvaddr, sizeof(recvaddr));if (-1 == ret_connect){perror("connetc error!\n");return -1;}openfd = open("./1.png", O_RDONLY);if (-1 == openfd){perror("open error!\n");return -1;}strcpy(msg.filename, "2.png");ret_stat = stat("./1.png", &st);if (-1 == ret_stat){perror("stat error!\n");return -1;}msg.total = st.st_size;while (1){bzero(msg.buf, sizeof(msg.buf));msg.rd_ret = read(openfd, msg.buf, sizeof(msg.buf));send(confd, &msg, sizeof(msg), 0);if (msg.rd_ret <= 0){break;}char buf[256] = {0};ret_recv = recv(confd, buf, sizeof(buf), 0);if (ret_recv <= 0){break;}usleep(1000 * 200);}close(confd);close(openfd);return 0;
}
4. recv.c
#include "head.h"typedef struct
{char buf[1024];char filename[32];int rd_ret;int total;
}MSG;int main(int argc, char const *argv[])
{int listfd = 0;int ret_bind = 0;int ret_listen = 0;int confd = 0;ssize_t ret_recv = 0;ssize_t ret_send = 0;struct sockaddr_in recvaddr;struct sockaddr_in sendaddr;socklen_t addrlen = sizeof(sendaddr);MSG msg;listfd = socket(AF_INET, SOCK_STREAM, 0);if (-1 == listfd){perror("socket error!\n");return -1;}bzero(&recvaddr, sizeof(recvaddr));bzero(&sendaddr, sizeof(sendaddr));bzero(&msg, sizeof(msg));recvaddr.sin_family = AF_INET;recvaddr.sin_port = htons(50000);recvaddr.sin_addr.s_addr = inet_addr("192.168.0.109");ret_bind = bind(listfd, (struct sockaddr *)&recvaddr, sizeof(recvaddr));if (-1 == ret_bind){perror("bind error!\n");return -1;}ret_listen = listen(listfd, 3);if (-1 == ret_listen){perror("listen error!\n");return -1;}confd = accept(listfd, (struct sockaddr *)&sendaddr, &addrlen);if (-1 == confd){perror("accept error!\n");return -1;}int openfd = 0;int flag = 0;int total = 0;int current_size = 0;while (1){ret_recv = recv(confd, &msg, sizeof(msg), 0);if (ret_recv <= 0){break;}if (0 == msg.rd_ret){printf("file upload end\n");return -1;}if (0 == flag)//拿到文件总大小{openfd = open(msg.filename, O_WRONLY | O_CREAT | O_TRUNC, 0666);if (-1 == openfd){perror("open error!\n");return -1;}flag = 1;total = msg.total;}write(openfd, msg.buf, msg.rd_ret);current_size += msg.rd_ret;printf("%d / %d\n", current_size, total);char buf[256] = "go on";send(confd, buf, strlen(buf), 0);}close(confd);close(openfd);close(listfd);return 0;
}
相关文章:
嵌入式学习——网络编程(TCP)——day31
1. TCP和UDP的区别 TCP(Transmission Control Protocol,传输控制协议) UDP(User Datagram Protocol,用户数据报协议) 1.1 连接方式 TCP 是面向连接的协议,它在数据传输前需要通过三次握手建立…...
[STM32]定位器与PWM的LED控制
目录 1. 深入了解STM32定时器原理,掌握脉宽调制pwm生成方法。 (1)STM32定时器原理 原理概述 STM32定时器的常见模式 使用步骤 (2)脉宽调制pwm生成方法。 2. 实验 (1)LED亮灭 代码 测试效果 (2)呼吸灯 代码 测试效果 3.总结 1. 深入了解STM32定时器原…...
可视化数据科学平台在信贷领域应用系列五:零代码可视化建模
信贷风控模型是金融机构风险管理的核心工具,在信贷风险管理工作中扮演着至关重要的角色。随着信贷市场的环境不断变化,信贷业务的风险日趋复杂化和隐蔽化,开发和应用准确高效的信贷风控模型显得尤为重要。信贷风险控制面临着越来越大的挑战和…...
Windows 11广告植入“另辟蹊径”:PC Manager暗示若不使用必应搜索,你的系统可能需要“修复”
Edge浏览器近期增添了许多实用的新功能,如侧边栏、休眠标签页和沉浸式阅读器。话虽如此,浏览器中仍有一部分功能被部分用户视为“冗余软件”和不必要的累赘。 随着Windows 11用户逐渐习惯操作系统关键位置出现越来越多的广告,微软似乎正尝试以…...
一线教师教学工具汇总
亲爱的教师们!我们的教学工具箱里也该更新换代啦!今天,就让我来给大家安利一波超实用的教学神器: 百度文库小程序 —— 在线图书馆 百度文库,一个宝藏级的在线文档分享平台!在这里,你可以找到海…...
【数据结构】栈和队列-->理解和实现(赋源码)
Toc 欢迎光临我的Blog,喜欢就点歌关注吧♥ 前面介绍了顺序表、单链表、双向循环链表,基本上已经结束了链表的讲解,今天谈一下栈、队列。可以简单的说是前面学习的一特殊化实现,但是总体是相似的。 前言 栈是一种特殊的线性表&…...
一篇教会你CSS定位
前言:在网页布局的时候,我们需要将想要的元素放到指定的位置上,这个时候我们就可以使用CSS中的定位操作。 先让我们看一下本篇文章的大致内容: 目录 什么是定位 1.相对定位 2.绝对定位 3. 固定定位 4. 粘性定位 5. 定位层级…...
Hive的常规操作
Hive常规操作 hive常用交互命令 -e执行sql语句 [rootmaster ~]# hive -e "show databases";-f执行sql脚本 [rootmaster ~]# hive -f /usr/local/demo.sql查看hive中输入的所有命令 [rootmaster ~]# cat ~/.hivehistory操作库 创建库 语法: create…...
redis做为缓存,mysql的数据如何与redis进行同步呢?
让我们一步步来实现如何让MySQL数据库的数据和Redis缓存保持同步。想象一下,MySQL是一个大仓库,存放着所有重要的货物(数据),而Redis则像是一个快速取货窗口,让你能更快拿到常用的东西。为了让两者保持一致…...
【Map】集合总结
一、Map 之前学习的Collection集合体系是单列集合,即一次存取一个元素 Map是双列集合,一次存取一对元素,这一对儿称为键值对,key-value,且key是映射到value 所谓键映射到值,是指只能通过键找到值,无法通过值找键 Map中键不能重复!值允许重复 Map中一个键,只能对应一个值 Ma…...
SpringBoot实现发送邮件功能
目录 一、开启邮件服务 二、导入pom依赖 三、配置yml文件 四、发送邮件 4.1、发送文字邮件 4.2、发送html邮件 4.3、发送附件邮件 4.4、发送图片邮件 一、开启邮件服务 这里拿QQ邮箱举例。 翻到下面进行开启,之后获取授权码。 二、导入pom依赖 <dependency><…...
外观数列 ---- 模拟
题目链接 题目: 分析: 题目的意思如下:所以我们需要引用双指针来找到连续的字符有几个, 并添加到答案中, 接着将此字符添加到答案中, 让left right , 继续向后遍历整个字符串, 重复上面的操作将答案重新赋给字符串, 继续重复上述操作, 应该重复n - 1 次, 因为n为1的时候, 直…...
上心师傅的思路分享(二)
Druid monitor 与Springboot常见报错界面渗透小技巧 目录 前言 1.Druid monitor介绍 2.Druid未授权(1rank) 3.druid弱口令 4.Druid进一步利用 4.1 URL监控 4.2 Session监控 利用思路 EditThisCookie(小饼干插件) 5.SpringBoot Actuator未授权访问漏洞 5.1 简介 5…...
116页 | 2024年中国金融行业网络安全研究报告(免费下载)
以上是资料简介和目录,如需下载,请前往星球获取!!!...
基于fabric封装一个简单的图片编辑器(vue 篇)
介绍 前言vue demo版本react 版本 前言 对 fabric.js 进行二次封装,实现图片编辑器的核心功能。核心代码 不依赖 ui响应式框架vue ,react 都适用。 只写了核心编辑相关代码便于大家后续白嫖二次开发 核心代码我就没有打包发布 会 和 业务代码一起放到项目中。 vu…...
Linux中 .PHONY 和 all 在 Makefile 中的作用
1 .PHONY 和 all .PHONY 是 GNU make 工具中的一个特殊指令,用于指示某个目标是一个伪目标。伪目标并不对应于实际的文件,而是用来执行一系列命令的标识符。使用 .PHONY 的好处包括避免与现有文件同名造成的冲突,以及提高 make 的执行效率&am…...
Flutter 中的 FlexibleSpaceBar 小部件:全面指南
Flutter 中的 FlexibleSpaceBar 小部件:全面指南 Flutter 是一个由 Google 开发的跨平台 UI 框架,它提供了丰富的组件来帮助开发者构建高性能、美观的移动、Web 和桌面应用。在 Flutter 的组件库中,FlexibleSpaceBar 是一个与 SliverAppBar …...
每天一个数据分析题(三百五十四)-分析报表
分析报表的主要作用是通过可视化图表的形式将各种分析结果完整、准确地呈现给阅读者,帮助阅读者读懂数据,从而进一步发现数据背后隐藏的业务问题。下列说法正确的是? A. 静态报表的主要载体是电子表格工具 B. BI报表的数据源获取方式是应用…...
卫星通信频段有哪些
卫星通信使用到的频段涵盖L, S, C, Ku, Ka等,而最常用的频段是C(4~8GHz)和Ku(12~18GHz)频段,而Ka(27-40GHz)频段是后起之秀。目前地球赤道上空有限的地球同步卫星轨位几乎已被各国占满,C和Ku频段内的频率资源被大量使用,而Ka频段的…...
RobotMaster编程语言:深度探索与实践挑战
RobotMaster编程语言:深度探索与实践挑战 RobotMaster编程语言,作为机器人编程领域的一颗璀璨明珠,其独特性与复杂性吸引了无数探索者的目光。本文将从四个方面、五个方面、六个方面和七个方面深入剖析这一编程语言的奥秘,同时揭…...
[特殊字符] 智能合约中的数据是如何在区块链中保持一致的?
🧠 智能合约中的数据是如何在区块链中保持一致的? 为什么所有区块链节点都能得出相同结果?合约调用这么复杂,状态真能保持一致吗?本篇带你从底层视角理解“状态一致性”的真相。 一、智能合约的数据存储在哪里…...
测试微信模版消息推送
进入“开发接口管理”--“公众平台测试账号”,无需申请公众账号、可在测试账号中体验并测试微信公众平台所有高级接口。 获取access_token: 自定义模版消息: 关注测试号:扫二维码关注测试号。 发送模版消息: import requests da…...
地震勘探——干扰波识别、井中地震时距曲线特点
目录 干扰波识别反射波地震勘探的干扰波 井中地震时距曲线特点 干扰波识别 有效波:可以用来解决所提出的地质任务的波;干扰波:所有妨碍辨认、追踪有效波的其他波。 地震勘探中,有效波和干扰波是相对的。例如,在反射波…...
剑指offer20_链表中环的入口节点
链表中环的入口节点 给定一个链表,若其中包含环,则输出环的入口节点。 若其中不包含环,则输出null。 数据范围 节点 val 值取值范围 [ 1 , 1000 ] [1,1000] [1,1000]。 节点 val 值各不相同。 链表长度 [ 0 , 500 ] [0,500] [0,500]。 …...
Angular微前端架构:Module Federation + ngx-build-plus (Webpack)
以下是一个完整的 Angular 微前端示例,其中使用的是 Module Federation 和 npx-build-plus 实现了主应用(Shell)与子应用(Remote)的集成。 🛠️ 项目结构 angular-mf/ ├── shell-app/ # 主应用&…...
【JVM面试篇】高频八股汇总——类加载和类加载器
目录 1. 讲一下类加载过程? 2. Java创建对象的过程? 3. 对象的生命周期? 4. 类加载器有哪些? 5. 双亲委派模型的作用(好处)? 6. 讲一下类的加载和双亲委派原则? 7. 双亲委派模…...
Ubuntu系统多网卡多相机IP设置方法
目录 1、硬件情况 2、如何设置网卡和相机IP 2.1 万兆网卡连接交换机,交换机再连相机 2.1.1 网卡设置 2.1.2 相机设置 2.3 万兆网卡直连相机 1、硬件情况 2个网卡n个相机 电脑系统信息,系统版本:Ubuntu22.04.5 LTS;内核版本…...
数据结构第5章:树和二叉树完全指南(自整理详细图文笔记)
名人说:莫道桑榆晚,为霞尚满天。——刘禹锡(刘梦得,诗豪) 原创笔记:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 上一篇:《数据结构第4章 数组和广义表》…...
CSS3相关知识点
CSS3相关知识点 CSS3私有前缀私有前缀私有前缀存在的意义常见浏览器的私有前缀 CSS3基本语法CSS3 新增长度单位CSS3 新增颜色设置方式CSS3 新增选择器CSS3 新增盒模型相关属性box-sizing 怪异盒模型resize调整盒子大小box-shadow 盒子阴影opacity 不透明度 CSS3 新增背景属性ba…...
游戏开发中常见的战斗数值英文缩写对照表
游戏开发中常见的战斗数值英文缩写对照表 基础属性(Basic Attributes) 缩写英文全称中文释义常见使用场景HPHit Points / Health Points生命值角色生存状态MPMana Points / Magic Points魔法值技能释放资源SPStamina Points体力值动作消耗资源APAction…...
