北京网站备案注销/成都最新热门事件

北京网站备案注销,成都最新热门事件,网络推广有什么好的方法,潍坊住房和城乡建设局网站一.协议 协议是一种 "约定". socket api 的接口, 在读写数据时, 都是按 "字符串" 的方式来发送接 收的. 如果我们要传输一些 "结构化的数据" 怎么办呢? 其实,协议就是双方约定好的结构化的数据 像下面,两端都知道数据结构…

一.协议

协议是一种 "约定". socket api 的接口, 在读写数据时, 都是按 "字符串" 的方式来发送接 收的. 如果我们要传输一些 "结构化的数据" 怎么办呢? 其实,协议就是双方约定好的结构化的数据

像下面,两端都知道数据结构data的结构,我们可以直接传data数据的二进制吗?

理论可以,但如果两边平台不同,不兼容等导致出错。

eg.大小端问题 64位指针大小8 32位指针大小4

所以我们一般不通过二进制协议进行传输

所以我们一个怎么处理更复杂的、结构化的数据的传输呢?

二.序列化和反序列化

1.什么是序列化 反序列化

比如说我们传一个结构体data,里面包含 int x,char oper ,int y。

我们不要一个一个传,可以把成员元素整合成一个字符串,再传。这个就是序列化

但当我们获取到了这个字符串,怎么获取到里面包含的消息呢?

我们可以自己进行规定,每个元素间用空格进行隔开,依次进行获取。

根据制定的规则进行解包,获取元素,就是反序列化。

序列化: 你将结构体的各个成员转换成某种格式的字符串,以便传输或存储。例如,使用空格分隔成员。
反序列化: 接收端根据预定的规则解析字符串,并将其恢复为原始数据结构(结构体、对象等)。

2.JSON 序列化

Jsoncpp 是一个用于处理 JSON 数据的 C++ 库。它提供了将 JSON 数据序列化为字
符串以及从字符串反序列化为 C++ 数据结构的功能。Jsoncpp 是开源的,广泛用于各
种需要处理 JSON 数据的 C++ 项目中。

序列化方法:

1.使用 Json::Value 的 toStyledString 序列化:

优点:将 Json::Value 对象直接转换为格式化的 JSON 字符串

#include <iostream>
#include <string>
#include <jsoncpp/json/json.h>
int main()
{Json::Value root;root["name"] = "joe";root["sex"] = "男";std::string s = root.toStyledString();std::cout << s << std::endl;return 0;
}
$ . / test.exe
{
"name" : "joe",
"sex" : "男"
}

2.使用 Json::StreamWriter:

优点:提供了更多的定制选项,如缩进、换行符等。

#include <iostream>
#include <string>
#include <sstream>
#include <memory>
#include <jsoncpp/json/json.h>
int main()
{Json::Value root;root["name"] = "joe";root["sex"] = "男";Json::StreamWriterBuilder wbuilder; // StreamWriter 的工厂std::unique_ptr<Json::StreamWriter> writer(wbuilder.newStreamWriter());std::stringstream ss;writer->write(root, &ss);std::cout << ss.str() << std::endl;return 0;
}
$ . / test.exe
{
"name" : "joe",
"sex" : "男"
}

3.使用 Json::FastWriter:

比 StyledWriter 更快,因为它不添加额外的空格和换行符。

#include <iostream>
#include <string>
#include <sstream>
#include <memory>
#include <jsoncpp/json/json.h>
int main()
{Json::Value root;root["name"] = "joe";root["sex"] = "男";Json::FastWriter writer;std::string s = writer.write(root);std::cout << s << std::endl;return 0;
}
$ . / test.exe
{ "name":"joe","sex" : "男" }#include <iostream>
#include <string>
#include <sstream>
#include <memory>
#include <jsoncpp/json/json.h>
int main()
{Json::Value root;root["name"] = "joe";root["sex"] = "男";// Json::FastWriter writer;Json::StyledWriter writer;std::string s = writer.write(root);std::cout << s << std::endl;return 0;
}
$ . / test.exe
{
"name" : "joe",
"sex" : "男"
}

反序列化方法:

使用 Json::Reader:

#include <iostream>
#include <string>
#include <jsoncpp/json/json.h>
int main() {// JSON 字符串std::string json_string = "{\"name\":\"张三\",\"age\":30, \"city\":\"北京\"}";// 解析 JSON 字符串Json::Reader reader;Json::Value root;// 从字符串中读取 JSON 数据             序列化的字符串 进行反序列bool parsingSuccessful = reader.parse(json_string,root);if (!parsingSuccessful) {// 解析失败,输出错误信息std::cout << "Failed to parse JSON: " <<reader.getFormattedErrorMessages() << std::endl;return 1;}// 访问 JSON 数据std::string name = root["name"].asString();int age = root["age"].asInt();std::string city = root["city"].asString();// 输出结果std::cout << "Name: " << name << std::endl;std::cout << "Age: " << age << std::endl;std::cout << "City: " << city << std::endl;return 0;
}
$ . / test.exe
Name : 张三
Age : 30
City : 北京

访问 JSON 数据,int age = root["age"].asInt(); 如果是char c=root["age"].asInt(),也是用.asInt,没有.aschar。因为char类型就是整数

三.重新理解 read、write、recv、send 和 tcp 为什么支持全双工

全双工:通信双方可以同时进行双向数据传输。也就是说,发送和接收可以在同一时刻发生。

在任何一台主机上,TCP 连接既有发送缓冲区,又有接受缓冲区,所以,在内核
中,可以在发消息的同时,也可以收消息,即全双工。
这就是为什么一个 tcp sockfd 读写都是它的原因。
实际数据什么时候发,发多少,出错了怎么办,由 TCP 控制,所以 TCP 叫做传输控制协议。

在系统内部都有大量的报文,一部分是从发送缓冲区进行传输,另一部分是向接收缓冲区进行传输。如何进行管理,先描述,再组织。每个报头间用链表进行连接。

在socket结构中就包含两个队列,分别是发送队列,接收队列,对这两部份报头进行管理。

这两个队列分别用于存储发送和接收的报文头。每个队列可以通过链表来管理报文的顺序。

发送缓冲区和发送队列:发送缓冲区的内容一般是按照队列的顺序被处理的。数据首先进入发送队列(即缓冲区),然后按顺序被发送到远程主机。在TCP协议中,发送队列不仅仅是一个简单的队列,还会涉及到流量控制、拥塞控制等机制,确保发送方的速度不会超过接收方的处理能力。
接收缓冲区和接收队列:当数据到达本地系统时,接收队列会存放这些数据。接收队列的顺序和缓冲区管理相结合,确保应用程序能够以正确的顺序读取到接收到的数据。

四.ps axj 当前系统的进程信息

   PID  PGID   SID TTY      TIME CMD123  123    123 tty1     00:00:01 bash234  123    123 tty1     00:00:00 ps567  567    567 ?        00:00:10 my_process

PID(进程ID):进程的唯一标识符。
PGID(进程组ID):多个进程共享的组ID。(处在同一组的进程PGID相同,一般第一个是组长)
SID(会话ID):进程所属的会话ID。
TTY(终端):进程关联的终端(如果有)。
TIME(CPU时间):进程使用的CPU时间。
CMD:启动该进程的命令。

五.守护进程

1.前台进程 后台进程

像在命令行中直接sleep 100 启动的就是前台进程,如果在后面加& ,sleep 100 &就把这个进程在后台启动。

启动一个前台进程(例如,运行 sleep 100),该进程会占用终端。前台进程会占据整个终端的输入/输出流,因此你无法在命令行中执行其他命令(如 ls)直到这个前台进程完成。

2.fd 任务号 后台进程->前台进程

当我们启动了一个后台进程,怎么再把它放到前台呢?

fd+任务号

使用 jobs 命令可以列出当前 shell 会话中所有的后台任务,并显示每个任务的任务号(Job ID)和当前状态。

3.Ctrl+Z bg 任务号 前台进程->后台进程

1.ctrl+z 挂起前台进程,变为暂停状态。

2.bg+任务号 将挂起的进程放到后台,不能直接把前台进程放在后台。

4.后台进程和守护进程

当我们进行登录,系统会创建一个会话,这个会话中bash进程当作前台进程,与终端直接连接,建立后台进程不会直接接收用户的输入,也不会直接向终端输出数据,一般不输入输出重定向到其它文件。

如果我们退出登录,该会话的前台进程 终端都会关闭,里面的后台进程也会受到影响。

有没有办法退出时让该后端进程不受影响?

把该后端进程放到一个新的会话中,并且持续运行,不与任何终端关联,就是守护进程。

如何创建守护进程?

手动:

1.调用 fork():首先,进程调用 fork() 创建一个子进程,父进程退出,确保子进程不成为孤儿进程。
2.调用 setsid():子进程通过 setsid() 调用成为新会话的会话领导者,这样它就不再与控制终端关联。(不是是进程组的组长调用它。fork()子进程调用)
3.重定向输入输出:守护进程会将输入输出重定向到日志文件或 /dev/null (文件黑洞 不会保存数据),以确保不会干扰终端。
4.持续运行:守护进程通常进入无限循环,保持持续运行,处理后台任务。

#pragma once#include <iostream>
#include <cstdlib>
#include <signal.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>#define ROOT "/"
#define devnull "/dev/null"void Daemon(bool ischdir, bool isclose)
{// 1. 守护进程一般要屏蔽到特定的异常信号signal(SIGCHLD, SIG_IGN);signal(SIGPIPE, SIG_IGN);// 2. 成为非组长if (fork() > 0)exit(0);// 3. 建立新会话setsid();// 4. 每一个进程都有自己的CWD,是否将当前进程的CWD更改成为 / 根目录if (ischdir)chdir(ROOT);// 5. 已经变成守护进程啦,不需要和用户的输入输出,错误进行关联了if (isclose){::close(0);::close(1);::close(2);}else{int fd = ::open(devnull, O_WRONLY);if (fd > 0){// 各种重定向dup2(fd, 0);dup2(fd, 1);dup2(fd, 2);close(fd);}}
}

daemon:

int daemon(int nochdir, int noclose);

nochdir:如果为 1,守护进程将不改变当前工作目录;如果为 0,守护进程会将当前工作目录更改为根目录(/),以避免占用一个文件系统的目录。
noclose:如果为 1,守护进程不会关闭文件描述符。如果为 0,守护进程会关闭标准输入、标准输出和标准错误输出文件描述符。

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>int main() {// 将进程转变为守护进程if (daemon(0, 0) == -1) {perror("daemon");exit(1);}// 守护进程的工作while (1) {// 这里可以添加守护进程执行的任务sleep(10);  // 每10秒执行一次任务}return 0;
}

在原会话的后台进程会受到终端信号干扰、父进程退出以及会话管理的影响。

通过使用 setsid() 来创建新的会话,守护进程能够脱离终端和父进程的控制,确保在系统后台独立稳定地运行,避免受到干扰。

守护进程处于新的会话:

1.确保进程不被终端信号干扰

在原有会话中运行的进程通常会收到一些终端信号,尤其是当用户退出时,例如 SIGHUP 信号,通常会导致进程终止。守护进程必须避免这些信号的干扰,才能保证其在系统后台长时间稳定运行。

调用 setsid() 后,守护进程会脱离原会话,并成为一个新的会话的会话领导者,控制终端不再影响它。这确保了守护进程不会因为终端的关闭或会话的结束而被中断。

2.防止守护进程成为孤儿进程

在操作系统中,进程分为父进程和子进程。如果一个进程的父进程终止,该进程会被操作系统的 "init" 进程收养,成为孤儿进程。然而,守护进程希望在系统后台长期运行,它不希望被父进程或任何其他进程“收养”,而是希望有完全的独立性。

通过调用 setsid(),守护进程脱离了原会话,成为一个新的会话的会话领导者,这样它不再依赖任何父进程,确保它不会成为孤儿进程,也不会因为父进程的退出而终止。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/896856.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SQL命令详解之多表查询(连接查询)

目录 1 简介 2 内连接查询 2.1 内连接语法 2.2 内连接练习 3 外连接查询 3.1 外连接语法 3.2 外连接练习 4 总结 1 简介 连接的本质就是把各个表中的记录都取出来依次匹配的组合加入结果集并返回给用户。我们把 t1 和 t2 两个表连接起来的过程如下图所示&#xff1a; …

001-码云操作

码云操作 一、配置公钥1.官网地址1.进入 git bash2.查看生成的公钥3.设置到 Gitee4.测试 二、初始化一个项目1.新建仓库 一、配置公钥 方便后续提交代码不用填写密码 1.官网地址 官网地址&#xff1a;https://gitee.com/Git码云教程&#xff1a;https://gitee.com/help/arti…

30.[前端开发-JavaScript基础]Day07-数组Array-高阶函数-日期Date-DOM

JavaScript的DOM操作 &#xff08;一&#xff09; 1 什么是DOM&#xff1f; 认识DOM和BOM 深入理解DOM 2 认识DOM Tree DOM Tree的理解 3 DOM的整体结构 DOM的学习顺序 DOM的继承关系图 document对象 4 节点、元素导航 节点&#xff08;Node&#xff09;之间的导航&…

嵌入式学习前要了解的基础知识

一、电压和电流 在嵌入式开发中&#xff0c;电压和电流是两个基本的电气概念&#xff0c;对于理解和设计电子电路至关重要。它们直接影响到嵌入式系统的性能、功耗、可靠性和安全性。 电压&#xff08;Voltage&#xff09; 电压是电场力推动电荷移动的能力&#xff0c;通常以…

机器学习:强化学习的epsilon贪心算法

强化学习&#xff08;Reinforcement Learning, RL&#xff09;是一种机器学习方法&#xff0c;旨在通过与环境交互&#xff0c;使智能体&#xff08;Agent&#xff09;学习如何采取最优行动&#xff0c;以最大化某种累积奖励。它与监督学习和无监督学习不同&#xff0c;强调试错…

共轭梯度法笔记

一、梯度下降法 x k 1 x k − α ∇ f ( x k ) x_{k1} x_k - \alpha \nabla f(x_k) xk1​xk​−α∇f(xk​) 这是普通的梯度下降公式&#xff0c;有两个量是关键&#xff0c;步长 α \alpha α和方向 ∇ f ( x k ) \nabla f(x_k) ∇f(xk​)。这里的方向直接选择了梯度方向&…

我的世界1.20.1forge模组开发进阶物品(7)——具有动画、3D立体效果的物品

基础的物品大家都会做了对吧?包括武器的释放技能,这次来点难度,让物品的贴图呈现动画效果和扔出后显示3D立体效果,这个3D立体效果需要先学习blockbench,学习如何制作贴图。 Blockbench Blockbench是一个用于创建和编辑三维模型的免费软件,特别适用于Minecraft模型的设计…

SpringBoot接口自动化测试实战:从OpenAPI到压力测试全解析

引言&#xff1a;接口测试的必要性 在微服务架构盛行的今天&#xff0c;SpringBoot项目的接口质量直接影响着系统稳定性。本文将分享如何通过自动化工具链实现接口的功能验证与性能压测&#xff0c;使用OpenAPI规范打通测试全流程&#xff0c;让您的接口质量保障体系更加完备。…

微软具身智能感知交互多面手!Magma:基于基础模型的多模态AI智能体

作者&#xff1a; Jianwei Yang, Reuben Tan, Qianhui Wu, Ruijie Zheng, Baolin Peng, Yongyuan Liang, Yu Gu, MuCai, SeonghyeonYe, JoelJang, Yuquan Deng, Lars Liden, Jianfeng Gao 单位&#xff1a;微软研究院&#xff0c;马里兰大学&#xff0c;威斯康星大学麦迪逊分校…

Baklib云内容中台的核心架构是什么?

云内容中台分层架构解析 现代企业内容管理系统的核心在于构建动态聚合与智能分发的云端中枢。以Baklib为代表的云内容中台采用三层架构设计&#xff0c;其基础层为数据汇聚工具集&#xff0c;通过标准化接口实现多源异构数据的实时采集与清洗&#xff0c;支持从CRM、ERP等业务…

华为 VRP 系统简介配置SSH,TELNET远程登录

华为 VRP 系统简介&配置TELNET远程登录 1.华为 VRP 系统概述 1.1 什么是 VRP VRP&#xff08;Versatile Routing Platform 华为数通设备操作系统&#xff09;是华为公司数据通信产品的通用操作系统平台&#xff0c;从低端到核心的全系列路由器、以太网交换机、业务网关等…

从新加坡《Companion Guide on Securing AI Systems 》看可信AI全生命周期防护框架构建

从新加坡《AI系统安全指南配套手册》看可信AI全生命周期防护框架构建 一、引言 1.1 研究背景与意义 近年来,人工智能(AI)技术以前所未有的速度蓬勃发展,已然成为推动各行业变革与创新的核心驱动力。从医疗领域辅助疾病诊断,到金融行业的风险预测与智能投顾,再到交通领…

C++学习之C++初识、C++对C语言增强、对C语言扩展

一.C初识 1.C简介 2.第一个C程序 //#include <iostream> //iostream 相当于 C语言下的 stdio.h i - input 输入 o -output 输出 //using namespace std; //using 使用 namespace 命名空间 std 标准 &#xff0c;理解为打开一个房间&#xff0c;房间里有我们所需…

HTMLS基本结构及标签

HTML5是目前制作网页的核心技术&#xff0c;有叫超文本标记语言。 基本结构 声明部分位于文档的最前面&#xff0c;用于向浏览器说明当前文档使用HTML标准规范。 根部标签位于声明部分后&#xff0c;用于告知浏览器这是一个HTML文档。< html>表示文档开始&#xff0c;&l…

eMMC存储器详解(存储区域结构、EXT_CSD[179]、各分区介绍、主要引脚、命令格式与类型等)

读本篇博文所需要的先行知识 关于芯片内部的ROM的作用、工作原理的介绍&#xff0c;链接如下&#xff1a; https://blog.csdn.net/wenhao_ir/article/details/145969584 eMMC的物理结构、特点、用途 这个标题的相关内容见我的另一篇博文&#xff0c;博文链接如下&#xff1a…

杰和科技工业整机AF208|防尘+静音+全天候运行

在特殊的工业环境中&#xff0c;实现快速生产离不开各类工业计算机的强大支持。杰和科技工业计算机AF208&#xff0c;作为核心控制单元&#xff0c;凭借其坚固可靠的外壳、先进的散热技术以及紧凑灵活的部署特点&#xff0c;发挥着关键作用。 硬实力外壳&#xff0c;无惧尘埃 …

Lua | 每日一练 (4)

&#x1f4a2;欢迎来到张胤尘的技术站 &#x1f4a5;技术如江河&#xff0c;汇聚众志成。代码似星辰&#xff0c;照亮行征程。开源精神长&#xff0c;传承永不忘。携手共前行&#xff0c;未来更辉煌&#x1f4a5; 文章目录 Lua | 每日一练 (4)题目参考答案线程和协程调度方式上…

Fiji —— 基于 imageJ 的免费且开源的图像处理软件

文章目录 一、Fiji —— 用于科学图像处理和分析1.1、工具安装&#xff08;免费&#xff09;1.2、源码下载&#xff08;免费&#xff09; 二、功能详解2.0、Fiji - ImageJ&#xff08;Web应用程序&#xff09;2.1、常用功能&#xff08;汇总&#xff09;2.2、Fiji - Plugins&am…

PyQT(PySide)的上下文菜单策略设置setContextMenuPolicy()

在 Qt 中&#xff0c;QWidget 类提供了几种不同的上下文菜单策略&#xff0c;这些策略通过 Qt::ContextMenuPolicy 枚举类型来定义&#xff0c;用于控制控件&#xff08;如按钮、文本框等&#xff09;在用户右键点击时如何显示上下文菜单。 以下是 Qt::ContextMenuPolicy 枚举中…

【实战 ES】实战 Elasticsearch:快速上手与深度实践-1.2.2倒排索引原理与分词器(Analyzer)

&#x1f449; 点击关注不迷路 &#x1f449; 点击关注不迷路 &#x1f449; 点击关注不迷路 文章大纲 1.2.2倒排索引原理与分词器&#xff08;Analyzer&#xff09;1. 倒排索引&#xff1a;搜索引擎的基石1.1 正排索引 vs 倒排索引示例数据对比&#xff1a; 1.2 倒排索引核心结…