【Linux】基于UDP/TCP套接字编程与守护进程
目录
一、网路套接字编程
(一)基础概念
1、源IP地址与目的IP地址
2、端口号
3、TCP与UDP
4、网络字节序
(二)套接字编程接口
1、socket 常见API
2、sockaddr结构
(三)UDP套接字
1、UDP服务器创建流程
2、UDP客户端创建流程
3、创建 socket 套接字
4、绑定 socket 端口号
5、服务器客户端数据的发送与接收
(四)TCP套接字
1、TCP服务器创建流程
2、TCP客户端创建流程
3、创建 socket 套接字
4、绑定 socketI P地址与端口号
5、服务器设置监听状态
6、服务器获取客户端连接请求
7、客户端连接请求
二、守护进程
(一)概念
(二)函数接口
(三)模拟实现
一、网路套接字编程
(一)基础概念
1、源IP地址与目的IP地址
在网络中,IP地址就是用来标识处于网络中的一台主机的地址,而源IP地址就是发送主机的地址,而目的IP地址就是接收主机的IP地址。
2、端口号
在网路通信中,仅仅知道主机的地址是不够的。例如:当我们打开QQ并发送一条消息时,当接收主机收到该数据时是无法确定该数据是发给QQ的还是微信的。因此在网路通信中还需要 端口号。
端口号是传输层协议的内容。
- 端口号是一个2字节16位的整数;
- 端口号用于标识一台主机上的进程,在网络通信中,通过端口可以得知该数据一个交给哪一个进程;
- IP地址 + 端口号 能够标识网络上的某一台主机的某一个进程;
- 一个端口号只能被一个进程占用,但一个进程可以占用多个端口号。
网络通信的本质实际时进程间通信,那为什么不直接使用进程 PID 来代替端口号呢?
(1)使网络通信与操作系统解耦;
(2)我们知道进程 PID 是由操作系统给出的,当服务器重启后其PID很可能会发生改变,如果直接使用 PID 作为标识不便于网络通信。
因此在网络通信中,不仅有源IP地址和目的IP地址,还有源端口号和目的端口号。除此之外,操作系统内部维护了一张哈希表,用于映射端口号到进程PCB的地址。
3、TCP与UDP
TCP( 传输控制协议):
- 传输层协议
- 有链接
- 可靠传输
- 面向字节流
UDP(用户数据报协议):
- 传输层协议
- 无连接
- 不可靠传输
- 面向数据报
4、网络字节序
内存中的很多字节数据相对于内存地址有大端和小端之分,磁盘文件中的多字节数据相对于文件中的偏移地址也有大端小端之分,网络数据流同样有大端小端之分。
- TCP/IP协议规定,网络数据流应采用大端字节序,即低地址高字节;
- 如果发送主机是小端字节序,需先将数据转换为大端后发送;如果发送主机是大端字节序,则直接进行发送即可;但在实际编程时考虑到代码移植性,无论大端机还是小段机,向网络发送数据还是从网络接收数据统一进行转换;
- 发送主机和接收主机都按照低地址到高地址发送接收数据
考虑到网络字节序的问题,C语言为我们提供了库函数。
#include <arpa/inet.h>
uint32_t htonl(uint32_t hostlong);
uint16_t htons(uint16_t hostshort);
uint32_t ntohl(uint32_t netlong);
uint16_t ntohs(uint16_t netshort);
以上便是字节序转换函数,例如 htons() 表示将16位短整数从主机字节序转换到网络字节序,至于具体是否需要进行转换由函数内部决定。
同样对于IP地址也需要进行转换。
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
int inet_aton(const char *cp, struct in_addr *inp);
//将点分十进制字符串转换为 uint32_t 的网络字节序
in_addr_t inet_addr(const char *cp);
in_addr_t inet_network(const char *cp);
//将32位的IPv4地址转化为点分十进制字符串
char *inet_ntoa(struct in_addr in);
struct in_addr inet_makeaddr(int net, int host);
in_addr_t inet_lnaof(struct in_addr in);
in_addr_t inet_netof(struct in_addr in);
(二)套接字编程接口
1、socket 常见API
// 创建 socket 文件描述符 (TCP/UDP, 客户端 + 服务器)
int socket(int domain, int type, int protocol);
// 绑定端口号 (TCP/UDP, 服务器)
int bind(int socket, const struct sockaddr *address, socklen_t address_len);
// 开始监听socket (TCP, 服务器)
int listen(int socket, int backlog);
// 接收请求 (TCP, 服务器)
int accept(int socket, struct sockaddr* address, socklen_t* address_len);
// 建立连接 (TCP, 客户端)
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
2、sockaddr结构
socket API是一层抽象的网络编程接口,适用于各种底层网络协议,如IPv4、IPv6等,各种网络协议的地址格式并不相同。
在使用socket API时,无论是网络套接字还是域间套接字都需要强转为 struct sockaddr 类型,通过传入参数 socketaddr 的前16位操作系统可以分辨是哪种套接字,从而在内部切换对应的套接字结构。
//sockaddr 结构
/* Structure describing a generic socket address. */
struct sockaddr{__SOCKADDR_COMMON (sa_); /* Common data: address family and length. */char sa_data[14]; /* Address data. */};//sockaddr_in 结构
/* 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. *//* Pad to size of `struct sockaddr'. */unsigned char sin_zero[sizeof (struct sockaddr) -__SOCKADDR_COMMON_SIZE -sizeof (in_port_t) -sizeof (struct in_addr)];};//in_addr结构
/* Internet address. */
typedef uint32_t in_addr_t;
struct in_addr{in_addr_t s_addr;};
(三)UDP套接字
1、UDP服务器创建流程
1、创建套接字;
2、绑定IP地址和端口号;
3、接收数据、处理数据和发送数据。
2、UDP客户端创建流程
1、创建套接字;
2、客户端不需要显式 bind IP地址与端口号,该动作由操作系统完成;
3、发送数据、接收数据和对数据进行处理。
3、创建 socket 套接字
NAMEsocket - create an endpoint for communication
SYNOPSIS#include <sys/socket.h>int socket(int domain, int type, int protocol);
RETURN VALUEUpon successful completion, socket() shall return a non-negative
integer, the socket file descriptor. Otherwise, a value of -1 shall be returned
and errno set to indicate the error.
用途:服务器与客户端创建 socket 文件描述符(TCP/UDP)
参数
- domain:指定套接字的协议族,常见的协议族有AF_INET(IPv4网络通信)、AF_UNIX/AF_LOCAL(本地通信)
- type:指定套接字的类型。常见的类型有SOCK_STREAM(流套接字)和SOCK_DGRAM(数据报套接字)。
- protocol:套接字使用的具体协议,通常与 domain和 type配合使用。一般情况下,可以将其设置为 0,表示由操作系统根据 domain和 type自动选择合适的协议。
返回值:
- 如果成功会返回一个非负的整型值,表示套接字的文件描述符;
- 如果失败返回-1,并设置 error 来表示错误原因。
4、绑定 socket 端口号
NAMEbind - bind a name to a socket
SYNOPSIS#include <sys/socket.h>int bind(int socket, const struct sockaddr *address,socklen_t address_len);
RETURN VALUEUpon successful completion, bind() shall return 0; otherwise, -1 shall
be returned and errno set to indicate the error.
用途:将一个套接字与一个特定的IP地址和端口号绑定
参数:
- socket:套接字的文件描述符;
- address:指向 struct sockaddr 类型的指针,包含套接字将要绑定的地址信息。具体的地址结构根据协议族的不同而有所区别;
- address_len:地址结构的长度,通常使用 sizeof 来获取。
5、服务器客户端数据的发送与接收
NAMEsendto - send a message on a socket
SYNOPSIS#include <sys/socket.h>ssize_t sendto(int socket, const void *message, size_t length,int flags, const struct sockaddr *dest_addr,socklen_t dest_len);
RETURN VALUEUpon successful completion, sendto() shall return the number of bytes
sent. Otherwise, -1 shall be returned and errno set to indicate the error.
用途:从已连接的 socket 中发送数据,常用于通过 UDP 协议或其他支持无连接的协议发送数据。
参数:
- socket:套接字的文件描述符;
- message:发送数据的地址;
- length:发送数据的长度;
- flags:控制发送操作的标志,通常为0;
- dest_addr:指向 sockaddr 结构体指针,包含目标地址的信息;
- dest_len:dest_addr 的长度,以字节为单位。
返回值:
- 成功时返回发送的字节数;
- 失败时返回-1并设置错误码。
NAMErecvfrom - receive a message from a socket
SYNOPSIS#include <sys/socket.h>ssize_t recvfrom(int socket, void *restrict buffer, size_t length,int flags, struct sockaddr *restrict address,socklen_t *restrict address_len);
RETURN VALUEUpon successful completion, recvfrom() shall return the length of the
message in bytes. If no messages are available to be received and the peer
has performed an orderly shutdown, recvfrom() shall return 0. Otherwise,
the function shall return -1 and set errno to indicate the error.
用途:从套接字接收数据的函数,它可以接收来自网络的消息,并允许用户指定用于接收消息的缓冲区,常用于 UDP 协议和其他无连接协议中。
参数:
- socket:套接字的文件描述符;
- buffer:指向内存缓冲区的指针,用于存储接收到的数据;
- length:buffer缓冲区的大小;
- flags:控制接收操作的标志,通常为 0;
- address:指向 sockaddr 结构体的指针,接收端的信息由此填充;
- address_len:指向 address 结构体的指针,表示该结构体的长度。
返回值:
- 成功时返回接收到的字节数;
- 若无消息接收且接收方关闭连接则返回0;
- 失败时返回-1并设置错误码。
(四)TCP套接字
1、TCP服务器创建流程
1、创建套接字;
2、绑定IP地址和端口号;
3、设置 socket 处于监听状态;
4、等待获取客户端连接请求;
5、接收数据、处理数据和发送数据。
2、TCP客户端创建流程
1、创建套接字;
2、客户端不需要显式 bind IP地址与端口号,该动作由操作系统完成;
3、向服务器发送连接请求;
4、发送数据、接收数据和对数据进行处理。
3、创建 socket 套接字
同UDP,但传入参数不同。
//UDP
udpFd = socket(AF_INET, SOCK_DGRAM, 0);
//TCP
tcpFd = spcket(AF_INET, SOCK_STREAM, 0);
4、绑定 socketI P地址与端口号
同UDP,但传入参数不同。
5、服务器设置监听状态
NAMElisten - listen for socket connections and limit the queue of incoming
connections
SYNOPSIS#include <sys/socket.h>int listen(int socket, int backlog);
RETURN VALUEUpon successful completions, listen() shall return 0; otherwise, -1
shall be returned and errno set to indicate the error.
用途:在一个套接字上监听来自客户端的连接请求,主要用于面向连接的协议(如 TCP)。
参数:
- socket:套接字的文件描述符;
- blcklog:表示在套接字上等待连接的最大队列长度。
返回值:
- 成功时返回0;
- 失败时返回-1并设置错误码。
6、服务器获取客户端连接请求
NAMEaccept - accept a new connection on a socket
SYNOPSIS#include <sys/socket.h>int accept(int socket, struct sockaddr *restrict address,socklen_t *restrict address_len);
RETURN VALUEUpon successful completion, accept() shall return the non-negative
file descriptor of the accepted socket. Otherwise, -1 shall be returned and
errno set to indicate the error.
用途:在一个已监听的套接字上接受一个客户端的连接请求。
参数:
- socket:套接字的文件描述符;
- address:指向 sockaddr 结构体的指针,用来存储客户端的地址信息;
address_len:指向 socket_t 类型的指针,表示 address 缓冲区的长度。
返回值:
- 成功时返回一个新的套接字,该文件描述符用于与用户进行数据交换;
- 失败时返回-1并设置错误码。
7、客户端连接请求
NAMEconnect - connect a socket
SYNOPSIS#include <sys/socket.h>int connect(int socket, const struct sockaddr *address,socklen_t address_len);
RETURN VALUEUpon successful completion, connect() shall return 0; otherwise, -1
shall be returned and errno set to indicate the error.
用途:用于客户端向服务器发起连接请求。
参数:
- socket:套接字的文件描述符;
- address:指向 sockaddr 结构体的指针,结构体中包含了目标主机的 IP 地址和端口号等信息
- address_len:表示结构体 address 的长度。
返回值:
- 成功时返回0;
- 失败时返回-1并设置错误码。
二、守护进程
(一)概念
当我们登录云服务器并使服务器运行时,如果我们退出登录,云服务器上部署的服务器也会被关闭,如何使得部署的服务器不受用户登录注销的影响呢?
这时候就需要将服务器变为守护进程,守护进程的本质实际是一个孤儿进程。
当我们登录云服务器时会建立一个会话,一个会话只有一个前台进程和n个后台进程,作业之间可以前后台转换,但这些任务仍有可能收到用户登陆注销的影响。
而守护进程则是将目标进程独立出去成为一个新的会话,因此便不受用户的影响,可以一直运行下去。
其中SID则为会话ID,PGID为一个进程组的ID,该ID值与进程组组长的PID相同。
(二)函数接口
Linux生成守护进程的接口:
NAMEdaemon - run in the background
SYNOPSIS#include <unistd.h>int daemon(int nochdir, int noclose);Feature Test Macro Requirements for glibc (see feature_test_macros(7)):daemon(): _BSD_SOURCE || (_XOPEN_SOURCE && _XOPEN_SOURCE < 500)
RETURN VALUE(This function forks, and if the fork(2) succeeds, the parent
calls _exit(2), so that further errors are seen by the child only.) On
success daemon() returns zero. If an error occurs, daemon() returns -1
and sets errno to any of the errors specified for the fork(2) and setsid(2).
用途:将程序放到后台运行的函数,通常在编写守护进程(daemon process)时使用。
参数:
- nochdir:如果这个参数为非零值,表示守护进程在后台运行时不会改变当前工作目录,如果设置为 0,则守护进程会将当前工作目录更改为根目录
/
,通常为了避免守护进程锁定在某个目录中,导致无法卸载该目录;- noclose:如果该参数为非零值,表示守护进程不会关闭标准输入、标准输出和标准错误输出文件描述符(即不调用
close()
)。如果设置为0
,守护进程会关闭这些文件描述符。通常,为了避免守护进程继承父进程的终端输出,会关闭这些文件描述符。返回值:
- 成功时返回0;
- 失败时返回-1并设置错误码。
(三)模拟实现
在实现之前需知道一个函数:
NAMEsetsid - create session and set process group ID
SYNOPSIS#include <unistd.h>pid_t setsid(void);
RETURN VALUEUpon successful completion, setsid() shall return the value of the
new process group ID of the calling process. Otherwise, it shall return
(pid_t)-1 and set errno to indicate the error.
用途:创建一个新的会话(session)并使当前进程成为新的会话领导进程并且不会收到终端的控制。进程组的组长不能调用setsid()函数来创建一个新的会话。
参数:无
返回值:
- 成功时返回该会话的ID
- 失败时返回-1并设置错误码
#include <iostream>
#include <signal.h>
#include <unistd.h>
#include <cassert>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
using namespace std;
//数据黑洞,向它写入的数据会被吃掉,读取数据什么都读不到(不会使进程退出)
#define DEV "/dev/null"
void daemonSelf(const char *currPath = nullptr)
{signal(SIGPIPE, SIG_IGN);//创建子进程 使子进程成为守护进程if (fork() > 0)exit(0);pid_t id = setsid();assert(id != -1);int fd = open(DEV, O_RDWR);if (fd >= 0){//创建成功重定向dup2(fd, 0);dup2(fd, 1);dup2(fd, 2);}else{//创建失败手动关闭close(0);close(1);close(2);}if (currPath)chdir(currPath);
}
相关文章:

【Linux】基于UDP/TCP套接字编程与守护进程
目录 一、网路套接字编程 (一)基础概念 1、源IP地址与目的IP地址 2、端口号 3、TCP与UDP 4、网络字节序 (二)套接字编程接口 1、socket 常见API 2、sockaddr结构 (三)UDP套接字 1、UDP服务器创建…...
springboot 引入前端
前端 打包 npm run build vue.config.js 文件 publicPath 默认建议保持 / publicPath: ‘/’ 后端 目录 粘贴下面目录之一: src/main/resources/static/ src/main/resources/public/ 补充(用的少) server:servlet:context-path: /thirdAdm…...

RTSP/Onvif安防平台EasyNVR接入EasyNVS显示服务缺失的原因与解决方案
EasyNVS云管理平台具备强大的汇聚与管理功能,支持EasyGBS、EasyNVR等平台的接入,能够将接入的视频资源进行统一输出,提供远程可视化运维等管理功能,特别适合解决设备现场没有固定公网IP但仍需在公网直播的需求。 在某次用户现场部…...

算法系列之回溯算法
在计算机科学领域,算法是解决问题的核心。回溯算法作为一种经典的算法设计技巧,以其试错和回退的思想,在解决许多复杂问题时展现出强大的能力。本文将深入探讨回溯算法,包括其核心概念、实现步骤、代码示例以及适用场景࿰…...
Uniapp 小程序接口封装与使用
深入理解 Uniapp 小程序接口封装与使用 在 Uniapp 小程序开发中,接口请求是获取和交互数据的关键部分。合理地封装接口不仅能提高代码的可维护性,还能增强项目的健壮性。今天,我们就来详细探讨一下如何在 Uniapp 中进行接口封装、引入以及使…...

Harmony开发笔记(未完成)
一、感想 作为一名拥有11年经验的Android开发者,我亲历了Android从高速发展到如今面临“僧多粥少”的过程。技术的世界瞬息万变,没有一种技术能够让人依赖一辈子。去年初,我自学了鸿蒙系统,并顺利通过了鸿蒙官方的初级和高级认。…...

观成科技:海莲花“PerfSpyRAT”木马加密通信分析
1.概述 在2024年9月中旬至10月,东南亚APT组织“海莲花”通过GitHub发布开源安全工具项目,针对网络安全人员发起了定向攻击。通过对相关攻击活动进行分析,可以将其与一些海莲花的样本关联起来。这些样本的通信数据结构与海莲花此前使用的攻击…...
Spring Boot @Async 注解深度指南
Spring Boot Async 注解深度指南 一、核心使用要点 启用异步支持 必须在启动类或配置类添加 EnableAsync,否则异步不生效。 SpringBootApplication EnableAsync public class Application { ... }线程池配置 默认问题:Spring 默认使用 SimpleAsyncTaskEx…...

windows设置暂停更新时长
windows设置暂停更新时长 win11与win10修改注册表操作一致 ,系统界面不同 1.打开注册表 2.在以下路径 \HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WindowsUpdate\UX\Settings 右键新建 DWORD 32位值,名称为FlightSettingsMaxPauseDays 根据需求填写数…...

Orange 开源项目 - 集成百度智能云-千帆大模型
1 集成百度智能云-千帆大模型 百度智能云-千帆ModelBuilder百度智能云千帆大模型服务与开发平台ModelBuilder(以下简称千帆ModelBuilder)是面向企业开发者的一站式大模型开发及服务运行平台。千帆ModelBuilder不仅提供了包括文心一言底层模型和第三方开源…...

特斯拉 FSD 算法深度剖析:软件层面全解读
一、引言 特斯拉的 FSD(Full Self-Driving)系统作为自动驾驶领域的前沿成果,其软件层面的算法设计至关重要。本文将从软件的角度,深入探讨特斯拉 FSD 所采用的算法,包括感知、规划、控制等多个方面,以期为…...
2025/2/17--2/23学习笔记(week1)_C语言
1 整数的存储 只有整数才有原码,反码,补码,原码取反加一(除了符号位)得到补码。补码的补码会变成原码。 在任何位运算里,都是操作的补码,因为整数在内存里都是以补码存储的 2 移位运算符 移位…...

数据结构:二叉树的数组结构以及堆的实现详解
目录 一.树与二叉树 1.树的概念与相关术语: 2.二叉树: (1)定义: (2)特殊的二叉树: (3)完全二叉树 (4)二叉树的存储结构&#x…...

AWS S3 如何设置公开访问权限?
1.让整个bucket都有公开访问权限 1.1关闭【阻止公共读】 1.2关闭ACL访问控制 1.3打开桶策略 这样桶内所有的图片就能访问了 2.只开放特定文件让其具有访问权限? 2.1关闭【阻止公共读】 如之前的图示 2.2打开ACL控制 2.3单个文件打开公共读...

使用TortoiseGit配合BeyondCompare实现在Git仓库中比对二进制文件
使用TortoiseGit的比对工具可以直接右键,点击选择比对和上一版本的变化差异: 但是TortoiseGit只能支持比对纯文本文件的变化差异,如果尝试比对二进制文件,会提示这不是一个有效的文本文件: BeyondCompare可以比对二进制…...

8、HTTP/1.0和HTTP/1.1的区别【高频】
第一个是 长连接: HTTP/1.0 默认 短连接,(它也可以指定 Connection 首部字段的值为 Keep-Alive实现 长连接)而HTTP/1.1 默认支持 长连接,HTTP/1.1是基于 TCP/IP协议的,创建一个TCP连接是需要经过三次握手的…...

Rk3568驱动开发_开发环境的搭建_1
1、环境说明: 需要用官方的程序包,这个程序需要在虚拟机里编译再将镜像烧录到板子里,本质上是给板子上一套Linux操作系统,镜像是.img文件 Linux操作系统被分成了多个模块,编译好后储存在镜像里,本质上就和…...

Solr中得Core和Collection的作用和关系
Solr中得Core和Collection的作用和关系 一, 总结 在Apache Solr中,Core和Collection 是两个核心概念,他们分别用于单机模式和分布式模式(SolrCloud)中,用于管理和组织数据。 二,Core 定义&am…...

Visual Studio Code 远程开发方法
方法1 共享屏幕远程控制,如 to desk, 向日葵 ,像素太差,放弃 方法2 内网穿透 ssh 第二个方法又很麻烦,尤其是对于 windows 电脑,要使用 ssh 还需要额外安装杂七杂八的东西;并且内网穿透服务提供商提供的…...
如何看到 git 上打 tag 的时间
在 Git 中可以通过以下方法查看标签(tag)的创建时间: 使用 git show 命令: 运行以下命令可以查看某个特定标签的详细信息,包括创建时间: git show 输出中会包含 Tagger 的信息和 Date 字段,显示…...

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型
摘要 拍照搜题系统采用“三层管道(多模态 OCR → 语义检索 → 答案渲染)、两级检索(倒排 BM25 向量 HNSW)并以大语言模型兜底”的整体框架: 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后,分别用…...
Java 语言特性(面试系列2)
一、SQL 基础 1. 复杂查询 (1)连接查询(JOIN) 内连接(INNER JOIN):返回两表匹配的记录。 SELECT e.name, d.dept_name FROM employees e INNER JOIN departments d ON e.dept_id d.dept_id; 左…...

CTF show Web 红包题第六弹
提示 1.不是SQL注入 2.需要找关键源码 思路 进入页面发现是一个登录框,很难让人不联想到SQL注入,但提示都说了不是SQL注入,所以就不往这方面想了 先查看一下网页源码,发现一段JavaScript代码,有一个关键类ctfs…...
【Java学习笔记】Arrays类
Arrays 类 1. 导入包:import java.util.Arrays 2. 常用方法一览表 方法描述Arrays.toString()返回数组的字符串形式Arrays.sort()排序(自然排序和定制排序)Arrays.binarySearch()通过二分搜索法进行查找(前提:数组是…...
1688商品列表API与其他数据源的对接思路
将1688商品列表API与其他数据源对接时,需结合业务场景设计数据流转链路,重点关注数据格式兼容性、接口调用频率控制及数据一致性维护。以下是具体对接思路及关键技术点: 一、核心对接场景与目标 商品数据同步 场景:将1688商品信息…...

2.Vue编写一个app
1.src中重要的组成 1.1main.ts // 引入createApp用于创建应用 import { createApp } from "vue"; // 引用App根组件 import App from ./App.vue;createApp(App).mount(#app)1.2 App.vue 其中要写三种标签 <template> <!--html--> </template>…...

如何在看板中有效管理突发紧急任务
在看板中有效管理突发紧急任务需要:设立专门的紧急任务通道、重新调整任务优先级、保持适度的WIP(Work-in-Progress)弹性、优化任务处理流程、提高团队应对突发情况的敏捷性。其中,设立专门的紧急任务通道尤为重要,这能…...

IT供电系统绝缘监测及故障定位解决方案
随着新能源的快速发展,光伏电站、储能系统及充电设备已广泛应用于现代能源网络。在光伏领域,IT供电系统凭借其持续供电性好、安全性高等优势成为光伏首选,但在长期运行中,例如老化、潮湿、隐裂、机械损伤等问题会影响光伏板绝缘层…...
大数据学习(132)-HIve数据分析
🍋🍋大数据学习🍋🍋 🔥系列专栏: 👑哲学语录: 用力所能及,改变世界。 💖如果觉得博主的文章还不错的话,请点赞👍收藏⭐️留言Ǵ…...

分布式增量爬虫实现方案
之前我们在讨论的是分布式爬虫如何实现增量爬取。增量爬虫的目标是只爬取新产生或发生变化的页面,避免重复抓取,以节省资源和时间。 在分布式环境下,增量爬虫的实现需要考虑多个爬虫节点之间的协调和去重。 另一种思路:将增量判…...