【Linux】序列化与反序列化、会话与进程组、守护进程

一.序列化和反序列化

协议其实就是结构化的数据。但是再网络通信中,我们不直接发送结构化的数据给对方。我们一般会将结构化的数据序列化成字符串/字节流,然后通过网络在发送出去。而接收方收到之后,要对收到的字符串/流式数据进行反序列化,即还原成结构化的样子。

那么我们可以直接发送二进制对象么,这个结构化数据双方都能认识啊?

可以,但不建议。

可以是因为在操作系统内部,协议都是直接传递的结构体,因为所有的操作系统都是C语言写的。不会存在差异。

不建议是因为通信双方可能是不同的语言实现的,这导致它们对结构体的对齐规则可能有差异。导致接受的数据可能不完整。

二.使用jsoncpp库实现序列化和反序列化

1.序列化

#include <iostream>
#include <string>
#include <jsoncpp/json/json.h>int main()
{Json::Value root;root["name"] = "zhangsan";root["age"] = 18;root["sex"] = "man";// 1. 使用root.toStyledString()序列化std::string s1 = root.toStyledString();std::cout << s1 << std::endl;// 2. 使用StyledWriter对象的write方法进行序列化Json::StyledWriter writer;std::string s2 = writer.write(root);std::cout << s2 << std::endl;// 3. 使用FastWriter对象的write方法进行序列化Json::FastWriter wr;std::string s3 = wr.write(root);std::cout << s3 << std::endl;// 4. 使用StreamWriterBuidler 对象new一个witer对象// 通过new出来的对象,将root数据,写入到一个字符串流中Json::StreamWriterBuilder swb;std::unique_ptr<Json::StreamWriter> wri(swb.newStreamWriter());std::stringstream ss;wri->write(root, &ss);std::cout << ss.str() << std::endl;return 0;
}

2.反序列化 

#include <iostream>
#include <string>
#include <jsoncpp/json/json.h>int main()
{Json::Value root;root["name"] = "zhangsan";root["age"] = 18;root["sex"] = "man";// 1. 使用root.toStyledString()序列化std::string s1 = root.toStyledString();std::cout << s1 << std::endl;// 2.反序列化Json::Reader reader;reader.parse(s1, root);std::string name = root["name"].asString();int age = root["age"].asInt();std::string sex = root["sex"].asString();std::cout << "name->" << name << std::endl;std::cout << "age->" << age << std::endl;std::cout << "sex->" << sex << std::endl;
}

三.tcp支持全双工 

我们进行tcp socket编程时,是直接使用read、write接口使用sockf进行读写的。而且我们读写都使用的是同一个文件描述符。这也就说明了tcp是支持全双工的。这是因为tcp内部有两个缓冲区---接收缓冲区和发送缓冲区。

而read和write并不是直接将数据写入到网络中的,而是先将数据发送到发送缓冲区中,最后由tcp协议决定什么时候将缓冲区的数据发送到网络中。write也不是直接从网络中读,而是从接收缓冲区中读。

在发送数据的时候,tcp(传输控制协议)自主决定,什么时候发,发多少,出错了怎么办。

主机间通信的本质:把发送方的发送缓冲区内部的数据,拷贝到对端的接收缓冲区。 

四.会话

1.进程组 

进程是以进程组的方式来完成作业的。进程组是一个或多个进程的集合。

我们启动了一个sleep 1000 | sleep 2000 | sleep 3000 & 的后台程序。而这三个进程就组成了一个进程组。

 进程组id就是该进程组的组长id,也就是组长id的pid。

2.会话

而SID就是会话。当我们登录的时候,打开终端,ssh会为我们打开0,1,2文件描述符,然后进行程序替换,让bash运行。一登录终端,就会创建一个会话,此时会话中只有一个进程组,该进程组中只有一个bash进程。

一个会话内部会存在多个进程组。

 五.守护进程

我们目前运行的程序都是直接在当前会话中启动的。并且都是只有一个进程的进程组。而该进程是受用户终端的登录状态影响的。当我们退出登录,就会销毁会话,会话中的进程就有可能被影响。

对于服务器来说,作为一个常驻内存的进程,不应该受用户的登录和退出状态所影响。

为了避免登录和注销的影响,我们需要将进程进行守护进程化。

守护进程即该进程拥有一个独立的会话,并且再后台运行。

 使用setsid来使进程,守护进程化。

NAMEsetsid - creates a session and sets the process group IDSYNOPSIS#include <sys/types.h>#include <unistd.h>pid_t setsid(void);

setsid要求调用该函数的进程不能是进程组的组长。(进程组的组长退出了,进程组并不会销毁,直到该进程组中所有的进程都退出了,进程组才消失)。

所以,我们可以采取fork子进程,并让父进程直接退出,让子进程执行setsid。

当然,我们也可以使用库里面的方法,实现守护进程化。

nochdir:是否将当前的工作目录转换为根目录

noclose:是否将0,1,0重定向到/dev/null文件,从该文件读只会读到null,写入该文件的内容都会被丢弃

NAMEdaemon - run in the backgroundSYNOPSIS#include <unistd.h>int daemon(int nochdir, int noclose);

下面是实现守护进程化的具体操作。  

#pragma once #include <iostream>
#include <string>
#include <signal.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>const std::string cwd = "/";
const std::string dev = "/dev/null";// 让网络服务器守护进程化
// 让启动的进程,独立成为一个进程组,并且占有独立的会话
// 守护进程化要求该进程不能是进程组的组长
void Daemon(int nochdir, int noclose)
{// 1. 守护进程忽略IO,以及子进程退出等相关信号signal(SIGPIPE, SIG_IGN);signal(SIGCHLD, SIG_IGN);// 2.必须得是一个进程组的组员,不能是组长if(fork() > 0) exit(0);// 下面就是子进程,也就是组员进程// 2.5 守护进程话setsid();// 3.守护进程执行时需要将其当前的工作目录改为/根目录if(nochdir == 0) chdir(cwd.c_str());// 4.守护进程本质上是一个孤儿进程,后台进程// 要避免其使用0,1,2与终端交互// 所以,将0,1,2重定向到/dev/null文件,该文件会将写入的内容丢弃,从该文件读,会读到nullptrif(noclose == 0){int fd = open(dev.c_str(), O_RDWR); // 以读写方式打开// 重定向// int dup2(int oldfd, int newfd); // dup2会使用oldfd,覆盖newfddup2(fd, 0);dup2(fd, 1);dup2(fd, 2);close(fd);}
}

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

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

相关文章

提权脚本Powerup命令备忘单

1. 获取与加载 从 GitHub 下载&#xff1a;(New-Object Net.WebClient).DownloadFile("https://raw.githubusercontent.com/PowerShellMafia/PowerSploit/master/Privesc/PowerUp.ps1", "C:\Temp\PowerUp.ps1")本地加载&#xff1a;Import-Module .\Power…

2025年Ai写PPT工具推荐,这5款Ai工具可以一键生成专业PPT

上个月给客户做产品宣讲时&#xff0c;我对着空白 PPT 页面熬到凌晨一点&#xff0c;光是调整文字排版就改了十几版&#xff0c;最后还是被吐槽 "内容零散没重点"。后来同事分享了几款 ai 写 PPT 工具&#xff0c;试完发现简直打开了新世界的大门 —— 不用手动写大纲…

部署docker上的redis,idea一直显示Failed to connect to any host resolved for DNS name

参考了https://blog.csdn.net/m0_74216612/article/details/144145127 这篇文章&#xff0c;关闭了centos的防火墙&#xff0c;也修改了redis.conf文件&#xff0c;还是一直显示Failed to connect to any host resolved for DNS name。最终发现是腾讯云服务器那一层防火墙没…

QML元素 - OpacityMask

QML 的 OpacityMask 用于通过遮罩元素的 透明度&#xff08;Alpha 通道&#xff09; 裁剪源元素的可见区域&#xff0c;适用于创建不规则形状的 UI 元素&#xff08;如圆形头像、波浪形进度条&#xff09;或复杂视觉效果。以下是详细使用技巧和常见场景示例&#xff1a; 1. 基本…

麒麟桌面系统文件保险箱快捷访问指南:让重要文件夹一键直达桌面!

往期文章链接&#xff1a;统信操作系统自定义快捷键配置音量调节功能指南 Hello&#xff0c;大家好啊&#xff0c;今天给大家带来一篇麒麟桌面操作系统上配置文件保险箱内文件夹桌面快捷方式的文章&#xff0c;欢迎大家分享点赞&#xff0c;点个在看和关注吧&#xff01;在日常…

LLM笔记(三)位置编码(1)

位置编码理论与应用 1. 位置编码如何解决置换不变性及其数学表现 在Transformer模型中&#xff0c;自注意力机制&#xff08;Self-Attention&#xff09;具有置换不变性&#xff08;permutation invariance&#xff09;&#xff0c;这意味着对输入序列的词元&#xff08;toke…

在人脸识别项目中ffmpeg有什么作用

在人脸识别项目中&#xff0c;FFmpeg 主要用于处理视频文件或流媒体数据。尽管 FFmpeg 本身并不是直接用于人脸识别的工具&#xff0c;但它通过其强大的多媒体处理能力&#xff0c;在很多方面间接支持了人脸识别任务的执行。以下是 FFmpeg 在人脸识别项目中的几个主要作用&…

问题 | 国内外软件定义卫星最新进展研究

软件定义卫星 **一、国内进展****二、国际进展****三、未来发展方向****总结** 软件定义卫星&#xff08;Software-Defined Satellite, SDS&#xff09;作为航天领域的重要技术革新方向&#xff0c;近年来在全球范围内发展迅速。其核心是通过开放式架构和动态软件配置实现卫星功…

【专利信息服务平台-注册/登录安全分析报告】

前言 由于网站注册入口容易被黑客攻击&#xff0c;存在如下安全问题&#xff1a; 暴力破解密码&#xff0c;造成用户信息泄露短信盗刷的安全问题&#xff0c;影响业务及导致用户投诉带来经济损失&#xff0c;尤其是后付费客户&#xff0c;风险巨大&#xff0c;造成亏损无底洞…

【Linux专栏】Linux进程间关系和守护进程

文章目录 1、进程间关系1.1 进程组1.2 组长进程 2、会话&#xff1f;2.1 查看会话2.2 创建会话 3、控制终端4、作业控制4.1 前台/后台进程 5、守护进程5.1 如何创建守护进程&#xff1f;5.2 杀掉守护进程 1、进程间关系 主要描述两个名称概念&#xff1a;即进程组和组长进程。…

电商物流管理优化:从网络重构到成本管控的全链路解析

大家好&#xff0c;我是沛哥儿。作为电商行业&#xff0c;我始终认为物流是电商体验的“最后一公里”&#xff0c;更是成本控制的核心战场。随着行业竞争加剧&#xff0c;如何通过物流网络优化实现降本增效&#xff0c;已成为电商企业的必修课。本文将从物流网络的各个环节切入…

ubuntu 更新华为源

1. 备份配置文件 sudo cp -a /etc/apt/sources.list /etc/apt/sources.list.bak 2. 修改source.list 文件&#xff0c;将http://archive.ubuntu.com和http://security.ubuntu.com替换成http://repo.huaweicloud.com&#xff0c;可以参考如下命令&#xff1a; # 第一条指令 s…

CS016-4-unity ecs

【37】将系统转换为任务 Converting System to Job 【Unity6】使用DOTS制作RTS游戏|17小时完整版|CodeMonkey|【37】将系统转换为任务 Converting System to Job_哔哩哔哩_bilibili a. 将普通的方法&#xff0c;转化成job。第一个是写一个partial struct xxx&#xff1b;第二…

如何使用 React Hooks 替代类组件的生命周期方法?

文章目录 1. 引言2. useEffect 概述3. 模拟类组件的生命周期方法3.1 模拟 componentDidMount3.2 模拟 componentDidUpdate3.3 模拟 componentWillUnmount 4. 多个 useEffect 的使用5. 注意事项6. 总结 1. 引言 在 React 16.8 版本之前&#xff0c;开发者主要通过类组件&#x…

盒带自编教材《软件工程》目录

目录 前言 第1章 软件工程概述 1.1 软件概述 1.1.1 软件的定义 1.1.2 软件的特点 1.1.3 软件的分类 1.1.4 软件的发展 1.2 软件危机 1.2.1 什么是软件危机 1.2.2 产生的原因及解决途径 1.3 软件工程 1.3.1 软件工程定义 1.3.2 软件工程的研究内容 1.3.3 软件工程的目标和原则…

CAN通信协议传输数据,为什么喜欢低位在前高位在后?而RS485则更倾向高位在前低位在后?

CAN 通信协议通常采用低位在前&#xff08;小端字节序&#xff09;&#xff0c;而 RS - 485 本身没有固定要求高位在前或低位在后&#xff0c;其数据传输顺序更多取决于具体应用和上层协议。 CAN 通信协议低位在前的原因 硬件设计与实现角度 逻辑电路处理便捷&#xff1a;数…

NGINX 安全性:持续进化的防护能力,为您的应用保驾护航

在数字时代,网络安全的重要性不言而喻。任何暴露在互联网上的应用都可能成为攻击者的目标。作为互联网基础设施的关键组成部分,NGINX 不仅是高性能的 Web 服务器和反向代理,更在应用安全防护方面扮演着至关重要的角色。它就像您数字资产的“第一道防线”和“智能门禁”,凭借…

makefile细节说明

在 Makefile中&#xff0c;依赖关系的左右两部分有特定的名称&#xff1a; ​​左边部分&#xff08;冒号左侧&#xff09;​​ 称为 ​​目标&#xff08;Target&#xff09;​​ ​​右边部分&#xff08;冒号右侧&#xff09;​​ 称为 ​​依赖项&#xff08;Prerequisite…

Zephyr OS Nordic芯片的Flash 操作

目录 概述 1. 软硬件环境 1.1 软件开发环境 1.2 硬件环境 2 Flash操作库函数 2.1 nRF52832的Flash 2.2 Nordic 特有的 Flash 操作 2.2.1 nrfx_nvmc_bytes_write 函数 2.2.2 nrfx_nvmc_page_erase函数 2.2.3 nrfx_nvmc_write_done_check 函数 3 操作Flash的接口函数…

03、基础入门-SpringBoot的大时代背景

03、基础入门-SpringBoot的大时代背景 # Spring Boot的大时代背景 Spring Boot的出现和发展&#xff0c;与以下时代背景密切相关&#xff1a; ## 1. 微服务架构的兴起 ### 背景 随着互联网应用的复杂度增加&#xff0c;传统的单体架构在扩展性、维护性和团队协作方面遇到瓶…