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

【Linux网络】Linux网络编程套接字,UDP与TCP

📝个人主页🌹:Eternity._
⏩收录专栏⏪:Linux “ 登神长阶 ”
🌹🌹期待您的关注 🌹🌹

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

❀Linux网络编程套接字

  • 📒1. 端口号
  • 📜2. 初识TCP协议与UDP协议
  • 📝3. 网络字节序
  • 📚4. socket编程
    • 🌄socket 常见API
    • 🌄sockaddr结构
    • 🌄封装 sockaddr_in
    • 🌄封装 Udp_Socket
    • 🌄封装 TCP_Socket
  • 🌞5. 进程守护
  • 🌙6. TCP协议通讯流程
  • ⭐7. TCP 和 UDP 对比
  • 📖8. 总结


前言:在当今这个信息技术日新月异的时代,网络编程已成为连接世界、构建各类互联网应用不可或缺的一部分。而Linux,作为开源操作系统的典范,其强大的网络功能和灵活性,为开发者们提供了一个广阔而深入的实践平台。在众多网络编程技术中,套接字(Socket)编程无疑是核心与基石,它不仅支撑着Web服务、即时通讯、在线游戏等日常应用,还是实现分布式系统、云计算服务的关键技术之一。

在套接字编程的世界里,UDP(用户数据报协议)与TCP(传输控制协议)如同双生子,各自以其独特的优势占据着不同的应用场景。TCP,以其可靠的连接导向、顺序传输和错误校正机制,成为了追求数据传输完整性和稳定性的不二之选,如文件传输、远程登录等场景;而UDP,则以其无连接、快速传输和较小的开销,在实时性要求高、对丢包容忍度较大的场合,如视频流、在线游戏等中大放异彩。

本文旨在深入探讨Linux环境下,如何通过套接字编程技术,驾驭UDP与TCP这两种强大的网络传输协议,从零开始构建基础的网络通信能力。

让我们一同踏上这段探索之旅,揭开Linux网络编程的神秘面纱,领略UDP与TCP的魅力所在,共同构建更加智能、互联的世界!


📒1. 端口号


概念:

端口号(port)是传输层协议的内容:

  • 端口号是一个2字节16位的整数
  • 端口号用来标识一个进程, 告诉操作系统, 当前的这个数据要交给哪一个进程来处理
  • IP地址 + 端口号能够标识网络上的某一台主机的某一个进程
  • 一个端口号只能被一个进程占用

注意:端口号和进程ID都可以唯一表示一个进程, 但是一个进程可以绑定多个端口号; 但是一个端口号不能被多个进程绑定

源端口号和目的端口号:

传输层协议(TCP和UDP)的数据段中有两个端口号,分别叫做源端口号和目的端口号

简单来说就是 “数据是哪个发的, 最后要发给谁


📜2. 初识TCP协议与UDP协议


TCP(Transmission Control Protocol 传输控制协议):

  • 传输层协议
  • 有连接
  • 可靠传输
  • 面向字节流

UDP(User Datagram Protocol 用户数据报协议):

  • 传输层协议
  • 无连接
  • 不可靠传输
  • 面向数据报

📝3. 网络字节序


网络字节序(Network Byte Order),也称为网络字节顺序,是协议中规定好的一种数据表示格式。它用于在计算机网络中进行数据通信时,统一数据的字节顺序,确保数据在不同主机之间传输时能够被正确解释。

因为内存中的多字节数据相对于内存地址有大端和小端之分,磁盘文件中的多字节数据相对于文件中的偏移地址也有大端小端之分,网络数据流同样有大端小端之分,为了定义出网络数据流的地址,我们引入了网络字节序

  • 发送主机通常将发送缓冲区中的数据按内存地址从低到高的顺序发出
  • 接收主机把从网络上接到的字节依次保存在接收缓冲区中,也是按内存地址从低到高的顺序保存
  • 因此,网络数据流的地址应这样规定:先发出的数据是低地址,后发出的数据是高地址
  • TCP/IP协议规定,网络数据流应采用大端字节序,即低地址高字节
  • 不管这台主机是大端机还是小端机, 都会按照这个TCP/IP规定的网络字节序来发送/接收数据
  • 如果当前发送主机是小端, 就需要先将数据转成大端; 否则就忽略, 直接发送即可

在这里插入图片描述

为使网络程序具有可移植性,使同样的C代码在大端和小端计算机上编译后都能正常运行,可以调用以下库函数做网络字节序和主机字节序的转换
在这里插入图片描述

在这里插入图片描述

  • h表示host,n表示network,l表示32位长整数,s表示16位短整数
  • htonl表示将32位的长整数从主机字节序转换为网络字节序,例如将IP地址转换后准备发送
  • 如果主机是小端字节序,这些函数将参数做相应的大小端转换然后返回
  • 如果主机是大端字节序,这些函数不做转换,将参数原封不动地返回

📚4. socket编程


🌄socket 常见API


常见通用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);

在这里插入图片描述

Udp中常见API:

// 函数用于在面向数据报的套接字(如UDP套接字)上发送数据
ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,const struct sockaddr *dest_addr, socklen_t addrlen);

在这里插入图片描述

// 用于从套接字接收数据的方法,特别是在使用UDP协议进行数据传输时
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,struct sockaddr *src_addr, socklen_t *addrlen);

在这里插入图片描述

Tcp中常见API:

// 开始监听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);

在这里插入图片描述

🌄sockaddr结构


sockaddr是一个在C语言网络编程中使用的数据结构,主要用于表示套接字地址。它是一个通用的结构体,能够用于表示不同类型的套接字地址,如IPv4、IPv6等

在这里插入图片描述

  • IPv4和IPv6的地址格式定义在netinet/in.h中,IPv4地址用sockaddr_in结构体表示,包括16位地址类型, 16位端口号和32位IP地址
  • IPv4、IPv6地址类型分别定义为常数AF_INET、AF_INET6。这样,只要取得某种sockaddr结构体的首地址,不需要知道具体是哪种类型的sockaddr结构体,就可以根据地址类型字段确定结构体中的内容
  • socket API可以都用struct sockaddr *类型表示,在使用的时候需要强制转化成sockaddr_in,这样的好处是程序的通用性,可以接收IPv4, IPv6, 以及UNIX Domain Socket各种类型的sockaddr结构体指针做为参数

sockaddr 结构:

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_); /* Port number. */in_port_t sin_port;	/* Internet address. */struct in_addr sin_addr;/* 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 int_addr
{in_addr_t s_addr;
};

🌄封装 sockaddr_in


我们在进行套接字编程时,难免会多次用到一些转换,我们不妨将他们封装起来,让我们的代码变得不那么复杂,从而更容易获取我们想要的数据

#pragma once
#include <iostream>
#include <string>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>using namespace std;class InetAddr
{
public:InetAddr(struct sockaddr_in &addr):_addr(addr){// 将网络字节流转换成字符串_port = ntohs(_addr.sin_port);_ip = inet_ntoa(_addr.sin_addr);}string Ip(){return _ip;}uint16_t Port(){return _port;}string PrintDebug(){string info = _ip;info += ":";info += to_string(_port);return info;}// 判断是否是同一个地址bool operator== (const InetAddr &addr){return _ip == addr._ip && _port == addr._port;}const sockaddr_in &GetAddr(){return _addr;   }~InetAddr(){}
private:string _ip;uint16_t _port;struct sockaddr_in _addr;
};

🌄封装 Udp_Socket


Udp_Server.hpp固定格式:

class UdpServer:public nocopy
{
public:UdpServer(uint16_t port):_port(port),_sockfd(defaultfd){}void Init(){// 创建套接字_sockfd = socket(AF_INET, SOCK_DGRAM, 0);if(_sockfd < 0){lg.LogMessage(Fatal, "socket err, %d : %s", errno, strerror(errno));exit(Socket_Err);}lg.LogMessage(Info, "socket success, sockfd: %d\n", _sockfd);// 绑定,指定网络信息struct sockaddr_in local;bzero(&local, sizeof(local)); // 初始化local.sin_family = AF_INET;local.sin_port = htons(_port);local.sin_addr.s_addr = INADDR_ANY; // 默认为 0// local.sin_addr.s_addr = inet_addr(_ip.c_str());// 结构填写完整,转到内核int n = ::bind(_sockfd, (struct sockaddr*)&local, sizeof(local));if(n != 0){lg.LogMessage(Fatal, "socket err, %d : %s", errno, strerror(errno));exit(Bind_Err);}}void Start(){// 服务器一直运行char buffer[defaultsize];for(;;){struct sockaddr_in peer;socklen_t len = sizeof(peer); // 不能乱写ssize_t n = recvfrom(_sockfd, buffer, sizeof(buffer) - 1, 0, (struct sockaddr*)&peer, &len);if(n > 0){// Server}}}~UdpServer(){pthread_mutex_destroy(&_mutex);}private:uint16_t _port;int _sockfd;
};

在这里插入图片描述

Udp实现聊天室功能

🌄封装 TCP_Socket


Tcp_Server.hpp固定格式:

class Tcp_Server : public nocopy // 防拷贝
{
public:Tcp_Server(uint16_t port, bool isrunning = false): _port(port), _isrunning(isrunning){}void Init(){// 创建套接字_listensock = socket(AF_INET, SOCK_STREAM, 0);if (_listensock < 0){lg.LogMessage(Fatal, "socket err, %d : %s", errno, strerror(errno));exit(Socket_Err);}lg.LogMessage(Info, "create socker success, sockfd: %d ... ", _listensock);// 固定写法int opt = 1;setsockopt(_listensock, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt));// 绑定,指定网络信息struct sockaddr_in local;memset(&local, 0, sizeof(local));local.sin_family = AF_INET;local.sin_port = htons(_port);local.sin_addr.s_addr = htonl(INADDR_ANY);// bindif (bind(_listensock, CONV(&local), sizeof(local)) != 0){lg.LogMessage(Fatal, "bind socket err, %d : %s", errno, strerror(errno));exit(Bind_Err);}lg.LogMessage(Debug, "bind socket success, sockfd: %d ... ", _listensock);// 监听 listenif (listen(_listensock, default_black_log) != 0){lg.LogMessage(Fatal, "listen socket err, %d : %s", errno, strerror(errno));exit(Listen_Err);}lg.LogMessage(Debug, "listen socket success, sockfd: %d ... ", _listensock);}// 通过read, write来进行数据的读写void Service(int sockfd){char buffer[1024];while(true){ssize_t n = read(sockfd, buffer, sizeof(buffer));if(n > 0){buffer[n] = 0;cout << "client say# " << buffer << endl;string echo_string = "server echo# ";echo_string += buffer;write(sockfd, echo_string.c_str(), echo_string.size());}else if (n == 0){lg.LogMessage(Info, "client quite ... \n");break;}else{lg.LogMessage(Error, "read socket err, %d : %s", errno, strerror(errno));break;}}}void Start(){_isrunning = true;// signal(SIGCHLD, SIG_IGN);while (_isrunning){// 获取连接struct sockaddr_in peer;socklen_t len = sizeof(peer);int sockfd = accept(_listensock, CONV(&peer), &len);if (sockfd < 0){lg.LogMessage(Fatal, "accept socket err, %d : %s", errno, strerror(errno));continue;}lg.LogMessage(Debug, "accept socket success, sockfd: %d ... ", sockfd);// 提供服务// v1Service(sockfd);close(sockfd);}}~Tcp_Server(){}private:uint16_t _port;int _listensock;bool _isrunning;
};

在这里插入图片描述

Tcp实现简单英译汉

🌞5. 进程守护


在之前的学习中,head -1我们经常使用,但是机会没机会了解PGID和SID是啥意思,今天我们来正式认识一下

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

我们同时创建的sleep 10000,sleep 20000,sleep 30000,会不会在同一个进程组里面呢?我们可以查询一下

在这里插入图片描述

移动进程组的指令:

查看任务:jobs
将任务放置到前台:fg task_number
将任务放置到后台:ctrl + Zdg task_number

在这里插入图片描述
守护进程:

守护进程是在后台运行的、不受任何终端控制的进程。它们通常用于执行系统级的任务或服务,如系统监控、网络通信、文件服务等。

在这里插入图片描述

封装 Daemon

🌙6. TCP协议通讯流程


TCP协议的客户端/服务器程序的一般流程:
在这里插入图片描述
建立连接的过程:

  • 调用socket, 创建文件描述符;
  • 调用connect, 向服务器发起连接请求;
  • connect会发出SYN段并阻塞等待服务器应答; (第一次)
  • 服务器收到客户端的SYN, 会应答一个SYN-ACK段表示"同意建立连接"; (第二次)
  • 客户端收到SYN-ACK后会从connect()返回, 同时应答一个ACK段; (第三次)

这个建立连接的过程, 通常称为 三次握手

断开连接的过程:

  • 如果客户端没有更多的请求了, 就调用close()关闭连接, 客户端会向服务器发送FIN段(第一次)
  • 此时服务器收到FIN后, 会回应一个ACK, 同时read会返回0 (第二次)
  • read返回之后, 服务器就知道客户端关闭了连接, 也调用close关闭连接, 这个时候服务器会向客户端发送一个FIN;(第三次)
  • 客户端收到FIN, 再返回一个ACK给服务器;(第四次)

这个断开连接的过程, 通常称为 四次挥手

⭐7. TCP 和 UDP 对比


  • 可靠传输 vs 不可靠传输
  • 有连接 vs 无连接
  • 字节流 vs 数据报

udp是面向用户数据包,而tcp面向字节流 — 数据和数据是有边界的

  • sendto、recvfrom ->sendto 发了一次,一定对应对端recvform一次 — 面向数据报
  • write->1,10,100->接收方read可能一次就全部收完了,也可能很多次,但是无论次数是多少,和对方发多少无关 — 面向字节流

📖8. 总结


在探索Linux网络编程的浩瀚领域中,UDP与TCP作为两大核心协议,不仅构建了互联网通信的基石,也成为了每一位网络开发者必须掌握的利器。通过这段旅程,我们一同见证了从基础概念到实践应用的华丽蜕变,从最初的套接字创建、绑定、监听,到数据的发送与接收,每一步都充满了挑战与收获。

在结束这篇文章之际,愿每一位读者都能在网络编程的世界里找到自己的位置,用代码编织梦想,用技术照亮未来。让我们携手前行,在Linux网络编程的广阔天地中,共同书写属于我们的辉煌篇章!

在这里插入图片描述

希望本文能够为你提供有益的参考和启示,让我们一起在编程的道路上不断前行!
谢谢大家支持本篇到这里就结束了,祝大家天天开心!

在这里插入图片描述

相关文章:

【Linux网络】Linux网络编程套接字,UDP与TCP

&#x1f4dd;个人主页&#x1f339;&#xff1a;Eternity._ ⏩收录专栏⏪&#xff1a;Linux “ 登神长阶 ” &#x1f339;&#x1f339;期待您的关注 &#x1f339;&#x1f339; ❀Linux网络编程套接字 &#x1f4d2;1. 端口号&#x1f4dc;2. 初识TCP协议与UDP协议&#x1…...

Vue3 -- 强制统一包管理器工具【企业级项目配置保姆级教程6】

引言: 团队开发项目的时候,需要统一包管理器工具,因为不同包管理器工具下载同一个依赖,可能版本不一样,导致项目出现bug问题,因此包管理器工具需要统一管理!!所以就需要我们强制统一包管理器工具。 创建scripts目录和preinstall.js文件: 在根目录创建scritps/preinstal…...

Winform实现自制浏览器JavaScript注入

让我们一起走向未来 &#x1f393;作者简介&#xff1a;全栈领域优质创作者 &#x1f310;个人主页&#xff1a;百锦再新空间代码工作室 &#x1f4de;工作室&#xff1a;新空间代码工作室&#xff08;提供各种软件服务&#xff09; &#x1f48c;个人邮箱&#xff1a;[1504566…...

【工具插件类教学】在 Unity 中使用 iTextSharp 实现 PDF 文件生成与导出

目录 一、准备工作 1. 安装 iTextSharp 2. 准备资源文件 二、创建 ExportPDFTool 脚本 1、初始化 PDF 文件,设置字体 2、添加标题、内容、表格和图片 三、使用工具类生成 PDF 四、源码地址 在 Unity 项目中,我们有时会需要生成带有文本、表格和图片的 PDF 文件,以便…...

javascript用来干嘛的?赋予网站灵魂的语言

javascript用来干嘛的&#xff1f;赋予网站灵魂的语言 在互联网世界中&#xff0c;你所浏览的每一个网页&#xff0c;背后都有一群默默工作的代码在支撑着。而其中&#xff0c;JavaScript就像是一位技艺精湛的魔术师&#xff0c;它赋予了网页生命力&#xff0c;让原本静态的页…...

Flutter Getx状态管理

在 Flutter 开发中&#xff0c;状态管理是一个非常重要的话题。随着应用变得更加复杂&#xff0c;状态管理的方式也变得越来越多。Flutter 提供了多种状态管理的解决方案&#xff0c;如 Provider、Riverpod、BLoC 等&#xff0c;而在这些选项中&#xff0c;GetX 作为一个轻量级…...

《成法》读书笔记

稻盛和夫的《成法》是一部关于个人和企业成功哲学的作品&#xff0c;结合了他在经营京瓷和KDDI&#xff0c;以及重建日航&#xff08;JAL&#xff09;过程中的经验和智慧。 以下是这本书的读书笔记&#xff0c;涵盖其核心思想和重要概念&#xff1a; 1. 以“心”为本 内容概…...

TensorFlow 2.0 环境配置

官方文档&#xff1a;CUDA Installation Guide for Windows 官方文档有坑&#xff0c;windows的安装指南直接复制了linux的指南内容&#xff1a;忽略这些离谱的信息即可。 可以从官方文档知悉&#xff0c;cuda依赖特定版本的C编译器。但是我懒得为了一个编译器就下载整个visua…...

Ekman理论回归

Scientific reportsEkman revisited: Surface currents to the left of the winds in the Northern HemisphereVagn Walfrid Ekman1905年的理论描述了地球旋转受到风的作用&#xff0c;摩擦边界层中的流场&#xff0c;北半球总是在海表风的右侧&#xff0c;南半球总是在海表风的…...

算法演练----24点游戏

给定4个整数&#xff0c;数字范围在1~13之间任意使用-*/&#xff08;&#xff09;&#xff0c;构造出一个表达式&#xff0c;使得最终结果为24&#xff0c; 方法一 算法分析&#xff1a;加括号和取出重复表达式 # 导入精确除法模块&#xff0c;使得在Python2中除法运算的行为更…...

【学习心得】Python好库推荐——tiktoken

一、tiktoken是什么&#xff1f; tiktoken是一个快速BPE分词器&#xff0c;是由 OpenAI 开发的一个用于文本处理的 Python 库&#xff0c;主要用于将文本编码为数字序列&#xff08;称为 "tokens"&#xff09;&#xff0c;或将数字序列解码为文本。这一过程被称为 &q…...

MacBook不额外安装软件,怎样投屏到安卓手机上?

提起iPhone或MacBook的投屏&#xff0c;人们总会想到airplay功能。但离开了苹果生态&#xff0c;其他品牌的手机电脑就未必配备airplay功能了。 如果想要将MacBook的电脑屏幕共享到安卓手机或平板上&#xff0c;到底要怎样做&#xff1f;需要安装什么软件吗&#xff1f; 不需要…...

flink sql + kafka + mysql 如何构建实时数仓

构建一个基于 Flink SQL、Kafka 和 MySQL 的实时数据仓库(Data Warehouse)架构,可以通过流处理的方式实现高效、实时的数据集成与分析。以下是如何利用这三者构建实时数仓的步骤与实现: 架构概述 Kafka:作为流数据平台,负责接收和传输来自不同源系统(如应用日志、传感器…...

Go语言开发基于SQLite数据库实现用户表查询详情接口(三)

背景 上一章 Go语言开发基于SQLite数据库实现用户表新增接口(二) 这一章我们实现用户表的查询详情接口 代码实现 mapper层 type UserMapper interface {GetById(id uint64) (*model.User, error)}type userMapper struct { }func (m *userMapper) GetById(id uint64) (*mod…...

(11)(2.1.7) FETtec OneWire ESCs(二)

文章目录 前言 3 组态 4 可选功能 5 SITL模拟 6 故障排除 前言 &#xff01;Note 此功能在固件版本4.1.1及更高版本上可用。 3 组态 FTW掩码 SERVO_FTW_MASK 参数选择将哪些伺服输出&#xff08;如果有的话&#xff09;路由到 FETtec ESC。更改此参数后需要重新启动。…...

Springboot maven常见依赖、配置文件笔记

pom.xml文件 一、<parent> 在Maven项目中&#xff0c;pom.xml 文件中的 <parent> 元素用于定义父项目的坐标。使用 <parent> 可以实现继承机制&#xff0c;子项目可以从父项目继承配置信息&#xff0c;比如依赖管理、插件配置等。这样可以避免在多个子项目…...

Ceph后端两种存储引擎介绍

Ceph是一个可靠的、自治的、可扩展的分布式存储系统&#xff0c;它支持文件系统存储、块存储、对象存储三种不同类型的存储&#xff0c;以满足多样存储的需求。在Ceph的存储架构中&#xff0c;FileStore和BlueStore是两种重要的后端存储引擎&#xff0c;下面将分别进行详细介绍…...

C++入门基础知识140—【关于C++ 类构造函数 析构函数】

成长路上不孤单&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a; 【14后&#x1f60a;///C爱好者&#x1f60a;///持续分享所学&#x1f60a;///如有需要欢迎收藏转发///&#x1f60a;】 今日分享关于C 类构造函数 & 析构函数的相关内容…...

基于标签相关性的多标签学习

✨✨ 欢迎大家来访Srlua的博文&#xff08;づ&#xffe3;3&#xffe3;&#xff09;づ╭❤&#xff5e;✨✨ &#x1f31f;&#x1f31f; 欢迎各位亲爱的读者&#xff0c;感谢你们抽出宝贵的时间来阅读我的文章。 我是Srlua小谢&#xff0c;在这里我会分享我的知识和经验。&am…...

macOS系统下使用SQLark连接达梦数据库

目录 下载 SQLark 客户端 安装 SQLark 客户端 SQLark用户界面 使用SQLark连接达梦数据库 1. 选择达梦数据库 2. 输入连接信息 3. 测试连接 4. 创建连接 5. 验证连接成功 作为一名数据库开发者&#xff0c;在macOS系统上找到一款支持达梦数据库的数据库开发和管理工具&…...

爬虫如何解决短效代理被封的问题?

在数据采集的征途上&#xff0c;短效代理如同一把双刃剑&#xff0c;它既能为我们带来速度和效率&#xff0c;也可能因为频繁更换IP地址而遭遇被封禁的风险。那么&#xff0c;作为数据采集er的我们&#xff0c;该如何巧妙应对&#xff0c;确保爬虫的稳定运行呢&#xff1f;今天…...

Jmeter基础篇(22)服务器性能监测工具Nmon的使用

一、前言 我们在日常做压测的过程中&#xff0c;不仅仅需要监控TPS&#xff0c;响应时间&#xff0c;报错率等这些系统基础性能数据&#xff0c;还需要对服务器的性能&#xff08;如CPU、磁盘、内存、网络IO等&#xff09;做监控&#xff0c;以求对系统运行过程中的硬件性能有…...

Spring Boot 集成 RabbitMQ:消息生产与消费详解

在现代微服务架构中&#xff0c;消息队列扮演着至关重要的角色&#xff0c;RabbitMQ 是其中一种广泛使用的消息中间件。本文将详细介绍如何在 Spring Boot 项目中集成 RabbitMQ&#xff0c;实现消息的生产和消费&#xff0c;并提供相应的代码示例。 一、环境准备与依赖配置 首…...

JSON-RPC-CXX深度解析:C++中的远程调用利器

一、引言 1. JSON-RPC 简介及其在 C 开发中的重要性 JSON-RPC&#xff08;JavaScript Object Notation - Remote Procedure Call&#xff09;是一种基于 JSON 格式的远程过程调用协议。在 C 开发中&#xff0c;它扮演着至关重要的角色。随着软件系统的日益复杂和分布式架构的…...

【后端速成Vue】模拟实现翻译功能

前言&#xff1a; 本期将会介绍 Vue 中的 watch 侦听器&#xff0c;它语法是怎么样的呢&#xff1f;具有怎样的功能呢&#xff1f;最后用模拟实现百度翻译来更进一步练习 watch 侦听器 篮球哥找工作专属IT岗位内部推荐&#xff1a; 专属内推链接&#xff1a;内推通道 1、认识翻…...

人脸识别技术:从算法到深度学习的全面解析

一、人脸识别技术综述 人脸识别技术作为一种重要的生物识别技术&#xff0c;在当今社会中具有举足轻重的地位。它广泛应用于各个领域&#xff0c;如金融领域的实名认证、安保领域的门禁系统、通行领域的火车站和地铁站检票、泛娱乐领域的美颜相机和短视频特效处理、公安和司法…...

WPF学习之路,控件的只读、是否可以、是否可见属性控制

C#的控件学习之控件属性操作 控件的只读、是否可以、是否可见&#xff0c;是三个重要的参数&#xff0c;在很多表单、列表中都有用到&#xff0c;正常表单控制可以在父层主键控制参数是否可以编辑和可见&#xff0c;但是遇到个别字段需要单独控制时&#xff0c;可以在初始化wi…...

植物神经紊乱不用怕,科学锻炼助你找回平衡✨

在这个快节奏、高压力的时代&#xff0c;你是否经常感到身心疲惫&#xff0c;情绪波动大&#xff0c;甚至偶尔还会出现心慌、失眠、消化不良等症状&#xff1f;这些可能都是植物神经功能紊乱在作祟&#xff01;&#x1f631;别担心&#xff0c;今天就来聊聊如何通过科学锻炼&am…...

shell 100例

1、每天写一个文件 (题目要求&#xff09; 请按照这样的日期格式(xxxx-xx-xx每日生成一个文件 例如生成的文件为2017-12-20.log&#xff0c;并且把磁盘的使用情况写到到这个文件中不用考虑cron&#xff0c;仅仅写脚本即可 [核心要点] date命令用法 df命令 知识补充&#xff1…...

CSS教程(二)- CSS选择器

1. 作用 匹配文档中的某些元素为其应用样式。根据不同需求把不同的标签选出来。 2. 分类 分类 基础选择器 包含 标签选择器、ID选择器、类选择器、通用选择器等 复合选择器 包含 后代选择器、子代选择器、伪类选择器等 1 标签选择器 介绍 又称为元素选择器&#xff0c;根…...