最新资讯

  • 一文搞懂 Linux 序列化 / 反序列化:原理分析与自定义协议实现详解

一文搞懂 Linux 序列化 / 反序列化:原理分析与自定义协议实现详解

2026-01-28 18:52:21 栏目:最新资讯 2 阅读

                🔥海棠蚀omo:个人主页

                ❄️个人专栏:《初识数据结构》,《C++:从入门到实践》,《Linux:从零基础到实践》,《Linux网络:从不懂到不会》

                ✨追光的人,终会光芒万丈

博主简介:

目录

一.序列化与反序列化

二.重新理解read,write,recv,send和TCP为什么支持全双工?

三.网络版计算器

3.1约定方案

3.2代码实现

3.2.1准备工作

3.2.2Socket封装

3.2.3TcpServer.hpp的实现

3.2.4protocol协议的实现

3.2.5客户端代码(Client.cc)和服务端代码(Main.cc)的实现

前言:

在 Linux 网络编程和系统开发中,序列化与反序列化几乎是绕不开的话题。无论是进程间通信,还是基于 Socket 的网络传输,数据最终都需要以字节流的形式在系统中流转。而很多初学者在实际开发中,往往只会“用协议”,却并不清楚协议是如何设计的、数据又是如何被序列化和还原的


今天我们将围绕 Linux 环境下的序列化与反序列化,从基本原理入手,逐步分析自定义协议的设计思路与实现方式,结合实际示例,帮助你真正搞懂数据在网络通信中的完整生命周期。

一.序列化与反序列化

在讲解什么是序列化与反序列化之前,我们先回顾一下之前我们讲解协议时的一些相关知识:

比如现在我要通过网络完成一个简单的计算器,即:完成两个数之间的运算,包括:加减乘除等,那么对于客户端和服务端而言,它们就要" 约定 "好所要传输的结构体中的内容,这其实就是" 自定义协议 "的体现。

就如上图所示的:两个要运算的数字和运算方式,即‘+ - * /’等符号,这样客户端将结构体发给服务端,服务端中也有该结构体类型,通过指针就能提取到客户端发来的数据。

但是这种直接传递结构体的方式会面临许多问题,如:

1.内存对齐问题。不同的编译器,不同的操作系统可能对于结构体的填充规则不同,既然不一致,那么双方在读取结构体中的数据时就会产生问题,可能就会读成乱码。

2.大小端问题。如果客户端是一个小端机器,服务端是一个大端机器,那么服务端在读取数据时就可能读反客户端所发来的数据。

3.适配性问题。就比如客户端是用C语言写的代码,所以传输时直接传递的也就是结构体,但是服务端却是用java或者Python语言写的,那么因为语言的差异性,服务端就很难完美模拟C内存中的物理布局。

但是操作系统之间确实就是以直接传递结构体的方式进行通信的,并且虽然上面我们列举了很多的问题,但是这些问题都可以被解决,至于具体是通过哪些方式来解决的这里不过多赘述,这不是我们要讲的重点。

当然任何事物都有两面性,这种方式既然有缺点,当然也有优点,这种方式的优点就是:极致的效率,直接传递结构体的这种方式可以使接收方直接把内存地址" 看成 "结构体,那么cpu的占用率就会很低,就几乎不用干活。

那么下面我们就来看看自定义协议的另一种编码方式:序列化与反序列化。

通过上面一张图就能解释何为序列化与反序列化,这里我们传递的不再是两个数字和运算方式,而是换成了传递一条聊天消息。

在这条聊天消息中,共有三个部分组成,它们分别表示什么含义由上层软件来解释,而这里我们选择的不再是将聊天信息的三个部分以结构体的形式进行传输,而是将结构体中的三个信息以空格分隔开,转换成一个字符串,通过网络传递给接收方。

而接收方在收到字符串后,会按照相同的转换原则,将字符串中的信息一一提取出来,交给上层处理。

将数据由结构体转化为字符串,即将信息由多变一,方便网络发送的过程就叫做:序列化,而通过相同的转化原则,将字符串转化为结构体,即将信息由一变多,方便上层处理的过程就叫做:反序列化。

那么为什么要进行序列化和反序列化呢?或者说序列化和反序列化相较于直接传递结构体有什么优点?

序列化:1.方便网络发送 2.方便协议的可扩展性和可维护性

对于第一点相信我们都能体会到,将信息由多变一,这就和多一事不如少一事一样,事情少了,自然也就更加的方便。

对于第二点所提到的可扩展性和可维护性,我们先说可扩展性,对于这一点我们打个比方:上面我们要发送的信息共有三个部分,接收方也只会解析这三个部分,而未来我们在结构体中增加了一些字段,比如:头像,性别等。

如果是直接传输结构体的方式,那么接收方也必须要同步的修改结构体中的字段,保持二者结构体中的字段是相同的,不然就会解析失败,但是序列化不需要这种同步工作,即这种方式支持新旧版本同时存在,至于如何做到的我们在下面实现时再说。

而后面的可维护性其实简单理解就是序列化没有上面列举的直接传输结构体的种种问题。

反序列化:方便上层处理

反序列化的优点就很明显了,它将所有的信息通过转化原则一个个提取出来,存入到相应的结构体中,那么上层在处理时直接访问该结构体拿到里面的数据即可,很方便。

所以所谓的自定义协议,本质其实就是制定双方都能认识的,符合通信和业务需要的结构化数据,所谓的结构化数据,其实就是struct或者class。

至此我们就完成了对序列化和反序列化的基本认识,而要想对序列化和反序列化有更深刻的认识,就需要下面我们动手来实操了。

二.重新理解read,write,recv,send和TCP为什么支持全双工?

在有了上面对于序列化和反序列化的认识后,下面我们来看一张图:

通过这张图我们就要来重新认识read,write,recv,send这些IO函数。

首先我们要知道当我们在使用Socket编程相关的api接口时,会在内核中形成发送缓冲区和接收缓冲区。

所以当我们使用上面那些IO函数来传递消息时,并不是真的把数据直接传送给对方了,而是将你要发送的内容拷贝到缓冲区中。

所以这里我们就可以输出第一个结论:write等IO函数的本质就是拷贝,发送数据是拷贝,读取数据也同样是拷贝!!!

那么下面就又会出现一个问题:那么我们通过write等函数将数据拷贝到缓冲区中,什么时候将数据发出去呢?发多少呢?

那么答案就是我们要输出的第二个结论:这些工作都由TCP自己来决定,所以TCP才叫做传输控制协议!!!

那么这里面还有一个隐性问题,那就是:发送的过程中数据发少了怎么办?

可能有人没看懂这个问题,就比如:当我们通过write函数向缓冲区中拷贝数据时,有没有可能缓冲区快满了,只能拷贝进去一部分?或者当TCP想要将数据发送到对方的接收缓冲区中时,对方的接收缓冲区也快满了,如果发送数据,也是只能发送一部分呢?

当然是有可能的,如果发送的数据缺斤少两,那么对方收到的消息也不会是完整的,那么可能就会出问题,而这种问题叫做:" 半包 "问题。

与半包问题相对应的还有一种问题叫做:" 粘包 "问题,这个问题产生的原因正好与半包问题相反。

" 粘包 "问题产生的原因就是:发送方一次性发送了多组数据,但是这几组数据都很小,而接收方的缓冲区又很大,所以可能会出现接收方通过read函数来读取数据时,直接将这几组数据一次性全读了出来,但是代价就是这几组数据" 粘 "在了一起,不知道每一组数据的开始和结束,这就是" 粘包 "问题。

" 半包 "问题或者" 粘包 "问题我们就需要自定义协议来解决,而在这里我们得先弄清TCP协议,UDP协议等协议与自定义协议的区别:

这里用生活中送快递的例子来说明,TCP协议等就像快递员一样,它们不关心包裹中的内容是什么,它们关心的只是将包裹从厂商送到你的手里,这中间出现的问题,如:包裹丢了,包裹少发了,包裹顺序乱了等这些问题它们会解决。

但是对于你收到的包裹中是否是你想要的东西,这与它们没有关系,这就与自定义协议有关,也就是你在网上下单,你买的是牛仔裤,厂家给你发的也是牛仔裤,这就相当于你和厂家" 约定 "好的一样,自定义协议管的就是包裹中的具体内容。

那么我们接着思考:TCP协议发送数据的时候,是怎么让数据出现在接收方的接收缓冲区中的呢?

答案就是拷贝,这里我们就要输出第三个结论了:主机间通信的本质就是把发送方发送缓冲区内部的数据,拷贝到接收方的接收缓冲区中,一样是拷贝。

那么下面我们就来思考:为什么TCP通信的时候,是全双工的,即在发送数据的同时也可以读取数据?

其实经过我们上面的讲解答案已经很明显了,第四个结论:就是因为有两对发送和接收缓冲区啊,不管是发送方还是接收方,都有一个发送缓冲区,一个接收缓冲区,它们之间互不影响,那么自然就可以做到全双工通信。

那么这里还有一个衍生问题:一个文件描述符有一套缓冲区,那么我们通过socket接口创建的多个文件描述符呢?

答案就是每一个通过socket接口成功创建的文件描述符,内核都会为它们分配一套独立的缓冲区,这其实也很好理解,未来可能会有多个客户端和服务端进行通信,每个客户端都应该有自己的缓冲区,而不是和别人共用一个缓冲区。

那么我们最后再来思考一个问题:用户通过write函数向缓冲区中拷贝数据,TCP从缓冲区中拿出数据将其拷贝到对端的缓冲区中,有没有感觉这种方式很熟悉呢?

当然熟悉了,因为这不就是我们之前讲的生产者消费者模型嘛,那么这里就要输出第五个结论:我们的任务,在每一个发送单元,都是一个cp问题,是用户和内核之间在进行生产和消费!!!

三.网络版计算器

3.1约定方案

这里我们先来规定一下我们的网络版计算器该怎样去实现,也就是" 约定 "客户端和服务端之间的传输的一些规则,下面我们来看:

约定方案一:

1.客户端发送的数据形式为" 1+2 "的字符串

2.这个字符串中有两个操作数,且都是整型,不能是浮点型等其他类型

3.两个数字之间会有一个字符是运算符,不能是其他字符

4.数字和运算符之间没有空格

约定方案二:

1.定义结构体来标识我们需要交互的信息

2.发送数据时将这个结构体按照一个规则转化成字符串,接受到数据的时候再按照相同的规则把字符串转化会结构体

以上就是我们在实现网络版计算器中客户端和服务端要遵守的规则。

3.2代码实现

在上一篇文章中我们使用了Socket编程的各种接口,而我们今天来玩点不一样的,我们自己来封装一个Socket接口类去使用。

而我们封装的Socket接口类我们使用一种常见的设计模式来实现,即:模板方法类,具体怎么来实现,下面我们就来看看吧。

3.2.1准备工作

那么首先呢我们先创建出这些文件,其中Main.cc和Client.cc分别表示服务端和客户端,剩下的我们基本都认识,前面都见过,唯独这里面的InetAddr.hpp我们之前没有见过。

#pragma once

// 这个类,描述client socket信息的类
// 方便我们后续用它来管理客户端

#include 
#include 
#include 
#include 
#include 
#include 
#include 

#define Conv(addr) ((struct sockaddr*)&addr)

class InetAddr
{
private:
    void Net2Host()
    {
        _port = ntohs(_addr.sin_port);
        // _ip = inet_ntoa(_addr.sin_addr);
        char ipbuffer[64];
        inet_ntop(AF_INET, &(_addr.sin_addr.s_addr), ipbuffer, sizeof(ipbuffer));
        _ip = ipbuffer;
    }
    void Host2Net()
    {
        memset(&_addr, 0, sizeof(_addr));
        _addr.sin_family = AF_INET;
        _addr.sin_port = htons(_port);
        // _addr.sin_addr.s_addr = inet_addr(_ip.c_str());
        inet_pton(AF_INET, _ip.c_str(), &(_addr.sin_addr.s_addr));
    }

public:
    InetAddr()
    {}
    InetAddr(const struct sockaddr_in &addr)
        : _addr(addr)
    {
        Net2Host();
    }
    InetAddr(uint16_t port, const std::string &ip = "0.0.0.0")
        : _port(port), _ip(ip)
    {
        Host2Net();
    }
    void Init(const struct sockaddr_in &addr)
    {
        _addr = addr;
        Net2Host();
    }
    std::string Ip()
    {
        return _ip;
    }
    uint16_t Port()
    {
        return _port;
    }
    struct sockaddr* Addr()
    {
        return Conv(_addr);
    }
    socklen_t Length()
    {
        return sizeof(_addr);
    }
    std::string ToString()
    {
        return _ip + "-" + std::to_string(_port);
    }
    bool operator==(const InetAddr &addr)
    {
        return (_ip == addr._ip && _port == addr._port);
        // return (_ip == addr._ip);
    }

    ~InetAddr()
    {
    }

private:
    struct sockaddr_in _addr; // 网络风格地址
    // 主机风格地址
    std::string _ip;
    uint16_t _port;
};

这个类我们是对Socket套接字进行了封装,便于我们完成主机序到网络序和网络序到主机序的转换,并且里面的方法也能够方便我们拿到IP地址和端口号。

这个类不是我们要讲的重点,所以这里我们就不过多赘述,直接用就行。

3.2.2Socket封装

那么下面我们就来看看模板方法类是怎么用的:

那么首先我们先定义一个Socket类,把它作为基类,里面有一些纯虚函数,未来是需要子类来实现的,包括:create,bind,listen这些我们熟知的创建套接字的流程函数,子类都要将其实现。

而基类中还有一个函数将这三个函数整合在一起,按顺序执行,所以我们未来执行的思路就是让基类指针指向子类对象,然后再让子类对象去调用它继承下来的Build函数,一次性调用者三个函数完成创建套接字的流程,这就是模板方法类。

那么不说废话,下面我们就来实现一下里面的几个函数:

这里我们创建一个TcpSocket的子类,由它来完成基类中相关函数的实现。

这里我们对于创建套接字过程中如果失败了我们要直接终止进程,所以我们通过枚举列举了几个变量,让代码看起来更美观,更直接。

之后我们再实现这三个函数时,分别要用到sockfd,port,backlog这三种属性,这三个函数都要用到sockfd,所以这里我们直接把sockfd给当成类内成员变量来使用,而对于backlog,它是已完成连接队列(Completed Connection Queue)的最大长度,这里我们直接将其默认为一个固定值即可。

所以未来我们只需要传入一个端口号即可,这里我们可以去看一下InetAddr.hpp中的相关实现,我们只传端口号即可,IP地址我们默认绑定的就是任意IP地址,即:0.0.0.0。

那么创建套接字的工作完成了,下面的工作自然就是连接了,那么下面我们就先来实现accept函数:

这就是目前要实现的Accept函数,对于Accept函数,我们不仅要它成功后返回的文件描述符,还要知道发送信息的客户端的相关属性,如:IP地址和端口号,这些信息都会保存在peer中,然后我们通过传进来的addr来调用Init函数,实现赋值操作,即可拿到客户端的相关信息。

而我们上面在实现时我们将返回值设置为我们自定义的Socket类,这样做的原因可以让我们未来创建出来的sockfd都能够使用我们所设计的Socket类,不然就只有listensockfd,即监听套接字能用,那我们就没有单独设计Socket类的意义了。

目前我们的Socket类就先实现到这里,后面我们有需要的功能再来实现。

3.2.3TcpServer.hpp的实现

那么下面我们就来着手实现服务端的相关功能。

有了上面铺垫,那么对于TcpServer我们就可以直接写出上面的内容,端口号不用多说,我们未来是要传给build函数的,所以将其作为成员变量无可厚非,而我们设计出Socket类,就是要用它,所以我们也不单独设计Init函数了,直接在构造函数中通过build函数完成初始化的工作。

那么完成了初始化的工作,下面就是让整个服务端运行起来,所以我们下面要实现一个run函数:

首先我们可以将Run函数实现到这个地步,这里我们采用多进程的方式来让服务端可以同时与多个客户端进行通信,来处理客户端的请求。

而要实现这一点我们就要解决父进程等待子进程结束的问题,如果不解决,父进程就必须得等待子进程结束才能接着执行,那么这种方式导致的结果就是服务端只能同时服务一个客户端。

可能有人不理解为什么,我们来设想一个场景:你作为客户端,是想让服务端能够长时间服务你还是服务一次直接挂掉了?
 

答案显然是第二种,那么服务端要处理客户端请求的函数或者功能一定是一个死循环,这样才能随时处理客户端的请求,那么既然是死循环,子进程什么时候结束就是未知数了,难道父进程要一直等吗?或者说你愿意排队吗?

我们当然不想等,我们要的就是客户端随时给服务端发送请求,服务端就要立刻处理我们的请求,所以我们不能让父进程一直在等待子进程。

当然这里的做法很多,我选择了一种较为简单的一种,就是利用信号,也算是回顾一下我们前面所学的知识。

那么在上面的代码中我们想要打印出新创建的文件描述符是多少,但是这里我们还没有实现,所以我们要在Socket类中实现一下:

实现这个功能很简单,这里不再多说。

那么下面就是父进程和子进程要做的事了,那么它们首先要做的就是关闭他们用不到的文件,也就是通过Close函数来关闭文件描述符所对应的文件,因为是多进程,所以文件是有引用计数的,所以不必担心文件被彻底关闭,那么下面我们就来实现一下该函数:

思路同样很简单,我们实现之后就可以用来关闭文件,对于子进程而言,它用不到listensocket,所以子进程要将其关闭,对于父进程而言,它用不到新创建的sockfd,所以父进程要将其关闭。

那么接下来就是子进程要干的事了,那就是处理客户端传来的请求,也就是要计算的字符串,下面我们接着看:

那么首先既然要处理客户端的请求我们就要先拿到客户端传进来的数据,所以这里我又设计了一个Recv函数用来接收客户端传来的数据,并对读取到的字节进行了简单的判断。

那么既然接收到了数据,那么我们先不谈怎么处理客户端传来的数据,那么我们肯定要将处理后的数据传回给客户端,所以下面我们先实现Send函数:

send函数实现完,我们就可以来实践一下了,看我们目前的代码能否支持客户端和服务端之间的通信。

上面就是我们所写的客户端和服务端可执行程序的代码,下面我们来简单运行一下试试:

从结果中我们可以看到此时我们的代码是可以进行通信的,但是我们也看到了我们通信的内容,也就是服务端返回的字符串一直在变长,这一点我们也能理解:

因为我们把要处理的字符串放在了外面,并且接收数据时我们是通过+=让其累加的,所以字符串会越来越长。

那么我这样写肯定是有原因的,我们在上面讲了可能会出现半包问题,那么我们如何判断读取的数据是否完整呢?

答案就是通过这种方式,只有这样我们才能判断读取的内容是否完整不是吗?

但是我们现在还没有说清楚,通过上面的讲述只是对于后面的设计有了一个大概的方向,那么下面我们就用三个问题确定最终的方向:

1.如何知道字符串in里面至少有一个完整的报文呢?

2.如何把这个完整的报文交给上层呢?

3.上层拿到了报文又该如何处理呢?

这三个问题就概括了我们后面要做的事,而这三个问题的答案又都与协议有关,所以下面我们就要将目光放在协议上面去了。

3.2.4protocol协议的实现

下面我们就来看看自定义协议中都有哪些东西:

我们曾经说过协议就是一个结构体,但那是站在C语言的角度来解释的,而我们今天是用C++来编写代码的,所以我们这里要用到的就是class类。

而在这里我们定义了两个类,分别是:Request和Response,这两个类分别用来处理请求和发送回复,因为我们要做的是一个计算器,所以Request类中要有要计算的两个数和运算符号。

Response类中我们要返回计算后的结果,而在该类中我又定义了一个_code的成员变量,这个变量用来表示可信度,就比如:如果客户端传来的是10 / 0,那么我们就无法给result一个准确的值,所以如果是这种情况,我们就需要_code变量来表明此时的result是不可信的,是错误的。

那么这两个类还需要做的事情就是完成序列化和反序列化,由它们完成序列化和反序列化后,再交给上层去进行处理,也就是计算结果,那么下面我们就要来了解怎么进行序列化与反序列化。

我们要实现序列化和反序列化就要用到Jsoncpp库,那么下面我们就来简单认识一下Jsoncpp库:

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

那么在该库中就提供了进行序列化和反序列化的相关接口,那么下面我们依次来认识一下。

序列化:

1.使用Json::Value的toStyledString方法

我们首先要定义一个Json库中的Value对象,这是一个万能对象,然后用法就是利用[]在里面填入你要用到的属性,=号后面就是该属性所对应的数据。

然后我们在通过Value对象的toStyledString函数进行转化,结果就如上面所示的那样,是一个结构化的数据,那么这时候有人就要问了:这怎么长得不像是一个字符串,更像是一个结构化的数据呢?

那是因为在生成的字符串中间利用了" "等特殊字符,让字符串看来更加美观,结构更加清晰。

那么有人就说:那我就想看看完整的一条长字符串呢?

2.使用Json::FsterWriter

如你所愿,我们可以定义一个FastWriter对象,通过调用该对象的write函数,将我们上面初始化后的Value对象给传进去,返回一个字符串,打印出的结果就是一个连续的长字符串。

序列化的方式还有很多种,剩下的我们就不再一一列举了,那么下面我们就来看看是如何进行反序列化的。

对于反序列化我们只介绍一种,那就是:使用Json::Reader,下面我们就来看看它是怎么使用的:

我们要创建一个Reader对象,并调用该对象的parse函数,该函数我们需要传入两个参数,第一个就是我们要反序列化的字符串,第二个就是要将反序列化后的结果存入一个Value对象中,所以我们还要创建一个Value对象。

而我们要打印的时候要用到Value对象的相关方法,如果里面是string类型的参数,就用asString,int类型就用asInt,其余皆是如此,但是char类型是没有的,我们可以用asInt代替。

至此我们对于序列化和反序列化的简单认识就到这里,下面我们就来着手写一下我们的Request和Response类:

上面的代码逻辑并不复杂,所以这里就不过多赘述了。

那么即使我们完成了序列化和反序列化的工作,依旧没有解决我们上面的问题,即:我们怎么知道字符串中有一个完整的报文呢?

所以仅仅完成序列化和反序列化的工作是不够的,而我们的做法则是给我们经过序列化的字符串添加一个报头,即:有效载荷长度,用它记录我们序列化后长字符串的长度,作为我们判断报文是否完整的一个标准。

所以下面就来完成上面的工作:

这里我们的做法是新创建一个Procotol类,在里面实现一个Package方法用来完成上面的工作,并且为了使我们最后的字符串可读性比较好,所以我们在中间添加了"  "。

最终该函数将返回一个完全体状态的一个报文,但是我们依旧没有解决上面所说的判断完整报文的问题,所以下面我们还要接着完善。

所有工作准备就绪下面我们就要彻底解决该问题,那么我们的思路就是将我们上面包装好的字符串origin_str传进去,并将其设置为输入输出型参数,至于为什么后面我们就知道了,并且我们传进去一个字符串package作为输出型参数,用来接收一个完整的报文。

那么下面我们就来实现一下该功能:

这里的实现思路我在上面已经通过注释进行了说明,这里我解释一下为什么要将origin_str设置成输入输出型参数:

代码的上面我们其实解决的都是半包问题,即读取的报文不完整,但是我们上面也说了,不止有半包问题,还可能会有粘包问题,而将origin_str设置成输入输出型参数就是为了解决粘包问题。

如果是粘包问题,那么我们截取一个完整的jsonstr后,再次调用该函数,得到的依旧是上次已截取出来的结果,所以为了避免影响后面的逻辑,这里必须要把一个完整的报文从origin_str中给去掉。

这里不理解的可以看上面我们当时在写protocol之前的测试,我们读到的字符串是一直在增加的,如果出现粘包问题,不将完整的报文去除掉,是会出问题的。

那么经过Unpack函数的调用后,我们就能拿到一个完整的jsonstr,那么下面我们就要对这个客户端传来的请求进行处理了,所以我们下面的思路就是解析客户端传来的请求,那么在实现该功能之前我们先来捋顺一下思路:

因为服务端只负责IO工作,所以对于解析客户端请求的工作肯定是不能交给服务端来完成的,所以这里我们让服务端将该工作交给其他人去完成,即通过function来完成函数的回调工作。

而我们将回调的函数返回值设置为string,参数也设置为string,返回值返回的就是我们未来要发给客户端的结果,而传进去的参数就是通过Recv读取到的字符串。

那么下面我们就来实现一下该回调函数:

这里我的做法是单独再创建一个Parser类来处理客户端的请求,里面的Parse函数就是用来完成该工作的。

上面实现的思路我也通过注释进行了说明,这里单独说一下最后为什么不直接将处理后的结果发给客户端而是要进行打包:

因为客户端未来也要从缓冲区中去读取服务端发来的数据,也同样会面临和服务端一样的半包问题和粘包问题,所以为了使客户端能够得到完整的结果,所以我们要对其进行打包,未来客户端也要执行和服务端一样的思路来保证报文的完整性。

上面我们也看到了,我们的解析工作中还缺少了处理客户端请求的工作,所以下面我们就要来实现该功能:

这里我的做法是创建一个Calculator类,在这个类中实现Exec函数来完成上面的工作,这里的逻辑也很简单,通过判断req对象中的运算符,通过switch语句就可以完成上面的工作,这里我只实现了常见的+,-,*,/,%五种运算。

当然,为了让该模块与Parser模块关联起来,我们要对Parser类做一些调整:

3.2.5客户端代码(Client.cc)和服务端代码(Main.cc)的实现

下面我们先在Main.cc,即服务端代码中将各个模块整合起来:

上面就是未来我们运行服务端的完整代码了,通过将服务器,Paser,Calculator这三个模块关联起来,我们就可以完成与客户端建立连接,解析客户端请求,处理客户端请求的全部工作了。

上面服务端的代码写完了,下面我们就来看看客户端的代码该怎么写吧:

上面就是客户端的完整代码,客户端中需要用到的一些额外的函数我都已经放在了上面,这些函数没什么难度,就不多讲了。

在实现客户端代码的过程中我们操作的可以看着下面这张图来一步一步进行:

这张图我们在最上面是见过的,按照这张图的顺序我们就能顺利地把客户端要做的事给顺下来。

那么所有工作已经准备就绪,下面我们就来看看我们实现的网络版计算器的实践效果:

从结果中可以看到网络计算器的功能已经实现了,包括除0问题等特殊情况我们也可以通过打印出来的_code来判断结果正确与否。

以上就是一文搞懂 Linux 序列化 / 反序列化:原理分析与自定义协议实现详解的全部内容。

本文地址:https://www.yitenyun.com/567.html

搜索文章

Tags

#服务器 #python #pip #conda #ios面试 #ios弱网 #断点续传 #ios开发 #objective-c #ios #ios缓存 香港站群服务器 多IP服务器 香港站群 站群服务器 #远程工作 #kubernetes #笔记 #平面 #容器 #linux #学习方法 #运维 #进程控制 #fastapi #html #css #低代码 #爬虫 #音视频 #docker #后端 #数据库 #cpolar #开源 #开发语言 #云原生 #iventoy #VmWare #OpenEuler #人工智能 #node.js #MobaXterm #ubuntu #Conda # 私有索引 # 包管理 #内网穿透 #网络 #RTP over RTSP #RTP over TCP #RTSP服务器 #RTP #TCP发送RTP #android #腾讯云 #c# #kylin #Trae #IDE #AI 原生集成开发环境 #Trae AI #数信院生信服务器 #Rstudio #生信入门 #生信云服务器 #物联网 #websocket #vscode #mobaxterm #深度学习 #计算机视觉 #tcp/ip #多个客户端访问 #IO多路复用 #回显服务器 #TCP相关API #web安全 #学习 #安全 #java #jar #nginx #claude #华为 #ModelEngine #金融 #大模型 #mcp #金融投资Agent #Agent #github #git #n8n #本地部署 #windows #hadoop #hbase #hive #zookeeper #spark #kafka #flink #qt #C++ #我的世界服务器搭建 #minecraft #MCP #科技 #自然语言处理 #神经网络 #todesk #算法 #jenkins #unity #游戏引擎 #需求分析 #scala #测试用例 #测试工具 #压力测试 #Dell #PowerEdge620 #内存 #硬盘 #RAID5 #MCP服务器 #性能优化 #缓存 #面试 #NPU #CANN #gemini #gemini国内访问 #gemini api #gemini中转搭建 #Cloudflare #vue.js #前端 #vue #阿里云 #JumpServer #堡垒机 #振镜 #振镜焊接 #云计算 #京东云 #gpu算力 #DisM++ # GLM-4.6V # 系统维护 #SRS #流媒体 #直播 #我的世界 #守护进程 #复用 #screen #umeditor粘贴word #ueditor粘贴word #ueditor复制word #ueditor上传word图片 #unity3d #游戏 #服务器框架 #Fantasy #ssh #http #c++ #mamba #智能手机 #java-ee #udp #910B #golang #rdp #mysql #sql #libosinfo #Dify #ARM架构 #鲲鹏 #网络协议 #jmeter #功能测试 #软件测试 #自动化测试 #职场和发展 #SSH反向隧道 # Miniconda # Jupyter远程访问 #c语言 #架构 #EMC存储 #存储维护 #NetApp存储 #自动化 #NAS #Termux #Samba #Linux #单片机 #ide #php #apache #risc-v #嵌入式硬件 #flask #GPU服务器 #8U #硬件架构 #centos #智能路由器 #5G #pycharm #stm32 #macos #C2000 #TI #实时控制MCU #AI服务器电源 #运维开发 #mvp #个人开发 #设计模式 #AI编程 #单元测试 #集成测试 #SAP #ebs #metaerp #oracle ebs #编辑器 #大数据 #搜索引擎 #DeepSeek #蓝耘智算 #Anaconda配置云虚拟环境 #Nacos #web #微服务 #YOLOFuse # Base64编码 # 多模态检测 #RustDesk #IndexTTS 2.0 #本地化部署 #ms-swift # 大模型 # 模型训练 #毕业设计 #车辆排放 #Android #Bluedroid #AI #工具集 #PyTorch # Triton # 高并发部署 #电气工程 #C# #PLC #微信 #oracle #wordpress #雨云 #LobeChat #vLLM #GPU加速 #spring #maven #tomcat #intellij-idea #ansible #海外服务器安装宝塔面板 #负载均衡 #翻译 #开源工具 #经验分享 #大模型部署 #mindie #大模型推理 #创业创新 #业界资讯 #计算机网络 #spring boot #openlayers #bmap #tile #server #milvus #langchain #大模型开发 #程序员 #redis #gitlab #课程设计 #CosyVoice3 # 语音合成 #机器学习 #chatgpt #Puppet # IndexTTS2 # TTS #语音识别 #说话人验证 #声纹识别 #CAM++ #codex #x86_64 #数字人系统 #yum #windows11 #microsoft #系统修复 #信令服务器 #Janus #MediaSoup #其他 #rtsp #转发 #unix #AIGC #三维 #3D #三维重建 #fpga开发 #分布式 #SQL注入主机 #javascript #json #rust #网络安全 #ping通服务器 #读不了内网数据库 #bug菌问答团队 #jvm #万悟 #联通元景 #智能体 #镜像 #大模型教程 #AI大模型 #大模型学习 #webrtc #idm #YOLO # GPU租赁 # 自建服务器 #数据分析 #推荐算法 #devops #客户端 #微信小程序 #小程序 #健身房预约系统 #健身房管理系统 #健身管理系统 #shell #渗透测试 #黑客技术 #计算机 #文件上传漏洞 #mcu #ThingsBoard MCP #react.js #debian #HeyGem # 服务器IP访问 # 端口映射 #A2A #GenAI #遛狗 #bug #密码学 #心理健康服务平台 #心理健康系统 #心理服务平台 #心理健康小程序 #鸭科夫 #逃离鸭科夫 #鸭科夫联机 #鸭科夫异地联机 #开服 #北京百思可瑞教育 #百思可瑞教育 #北京百思教育 #聊天小程序 #asp.net # 一锤定音 # 大模型微调 #deepseek #adb #nodejs #交互 #练习 #基础练习 #数组 #循环 #九九乘法表 #计算机实现 #dynadot #域名 #esb接口 #走处理类报异常 #vllm #cpp #项目 #高并发 #ffmpeg #数据挖掘 #CUDA #Triton #dify #部署 #语言模型 #昇腾300I DUO #fiddler #银河麒麟部署 #银河麒麟部署文档 #银河麒麟linux #银河麒麟linux部署教程 #opencv #Qwen3-14B # 大模型部署 # 私有化AI #vnstat #监控 #AI 推理 #NV #文心一言 #AI智能体 #pytorch #vp9 #攻防演练 #Java web #漏洞 #红队 #leetcode #screen 命令 #1024程序员节 #SSH跳板机 # Python3.11 #LVDS #高速ADC #DDR #东方仙盟 #API限流 # 频率限制 # 令牌桶算法 #驱动开发 #chrome #黑群晖 #虚拟机 #无U盘 #纯小白 #支付 #数据结构 #华为云 #screen命令 #排序算法 #Gunicorn #WSGI #Flask #并发模型 #容器化 #Python #性能调优 #蓝湖 #Axure原型发布 #gitea #门禁 #梯控 #智能一卡通 #门禁一卡通 #消费一卡通 #智能梯控 #一卡通 #源代码管理 #超时设置 #客户端/服务器 #网络编程 # 目标检测 #管道Pipe #system V #ai #ai编程 #机器人 #uv #uvx #uv pip #npx #Ruff #pytest #YOLO26 #目标检测 #react native #昇腾 #ida #web server #请求处理流程 #SSH # 批量管理 #ASR #SenseVoice #星图GPU #中间件 #MQTT协议 #交通物流 #C语言 #vivado license #CVE-2025-68143 #CVE-2025-68144 #CVE-2025-68145 #prometheus #grafana #svn #证书 #scrapy #可信计算技术 #openHiTLS #TLCP #DTLCP #商用密码算法 #ONLYOFFICE #MCP 服务器 #laravel #ssl # 双因素认证 # TensorFlow #服务器繁忙 #蓝牙 #LE Audio #BAP #serverless #RAID #RAID技术 #磁盘 #存储 #链表 #cursor #puppeteer #postgresql #连接数据库报错 #安全威胁分析 #仙盟创梦IDE #硬件工程 #智能家居 #动态规划 #pyqt #xlwings #Excel #DNS #dlms #dlms协议 #逻辑设备 #逻辑设置间权限 #国产化 #elasticsearch #django #web3.py #C #spring cloud #Spring AI #STDIO传输 #SSE传输 #WebMVC #WebFlux #bootstrap #nfs #iscsi #SPA #单页应用 #麒麟OS #文件管理 #文件服务器 #信息与通信 #信号处理 #tcpdump #swagger #visual studio code #transformer #prompt #mariadb #树莓派4b安装系统 #paddleocr #wsl #LangGraph #CLI #JavaScript #langgraph.json #ddos #银河麒麟高级服务器操作系统安装 #银河麒麟高级服务器V11配置 #设置基础软件仓库时出错 #银河麒高级服务器系统的实操教程 #生产级部署银河麒麟服务系统教程 #Linux系统的快速上手教程 #系统架构 #KMS激活 #jdk #排序 #numpy #CSDN #数据仓库 #sqlite # 水冷服务器 # 风冷服务器 #selenium #.netcore #VoxCPM-1.5-TTS # 云端GPU # PyCharm宕机 #儿童AI #图像生成 #Qwen #pjsip #LoRA # lora-scripts # 模型微调 #openresty #lua #https #智能体来了 #传统行业 #AI赋能 # PyTorch # CUDA #麒麟 #Syslog #系统日志 #日志分析 #日志监控 #生产服务器问题查询 #日志过滤 #p2p #Autodl私有云 #深度服务器配置 #SSH保活 #Miniconda #远程开发 #微PE # GLM-4.6V-Flash-WEB # AI部署 #everything #材料工程 #电脑 #数码相机 #智能电视 #能源 #人脸识别sdk #视频编解码 #人脸识别 #VMware创建虚拟机 #远程更新 #缓存更新 #多指令适配 #物料关联计划 #AI生成 # outputs目录 # 自动化 #挖漏洞 #攻击溯源 #编程 #stl #漏洞修复 #IIS Crypto #blender #warp #二值化 #Canny边缘检测 #轮廓检测 #透视变换 #DooTask #ZooKeeper #ZooKeeper面试题 #面试宝典 #深入解析 #Clawdbot #ComfyUI # 推理服务器 #防毒面罩 #防尘面罩 #n8n解惑 #编程助手 #.net #net core #kestrel #web-server #asp.net-core #elk #rabbitmq #uni-app #m3u8 #HLS #移动端H5网页 #APP安卓苹果ios #监控画面 直播视频流 #Prometheus #esp32 arduino #决策树 #Zabbix #语音合成 #HistoryServer #Spark #YARN #jobhistory #postman #内存接口 # 澜起科技 # 服务器主板 # 显卡驱动备份 #Socket #模拟退火算法 #计算机毕业设计 #程序定制 #毕设代做 #课设 #源码 #毕设 #VMware #简单数论 #埃氏筛法 #openEuler #Hadoop #TCP #嵌入式 #DIY机器人工房 #文件传输 #电脑文件传输 #电脑传输文件 #电脑怎么传输文件到另一台电脑 #电脑传输文件到另一台电脑 #身体实验室 #健康认知重构 #系统思维 #微行动 #NEAT效应 #亚健康自救 #ICT人 #eureka #云服务器 #个人电脑 #KMS 激活 #mongodb #wireshark #广播 #组播 #并发服务器 #nacos #银河麒麟aarch64 #MC #MC群组服务器 #uvicorn #uvloop #asgi #event # 服务器迁移 # 回滚方案 #制造 #大模型入门 #flutter #homelab #Lattepanda #Jellyfin #Plex #Emby #Kodi #yolov12 #研究生life #开关电源 #热敏电阻 #PTC热敏电阻 #asp.net大文件上传 #asp.net大文件上传下载 #asp.net大文件上传源码 #ASP.NET断点续传 #asp.net上传文件夹 #asp.net上传大文件 #excel #gpu #nvcc #cuda #nvidia #漏洞挖掘 #gpt #TensorRT # 推理优化 #SSH别名 #zabbix #CS2 #debian13 #BoringSSL #时序数据库 #企业存储 #RustFS #对象存储 #高可用 #notepad++ #es安装 #远程控制 #Docker #云计算运维 #模块 #STUN #turn #ICE #银河麒麟 #信创国产化 #达梦数据库 #CVE-2025-61686 #路径遍历高危漏洞 #RXT4090显卡 #RTX4090 #深度学习服务器 #硬件选型 #群晖 #音乐 # ARM服务器 # 鲲鹏 #IntelliJ IDEA #Spring Boot #neo4j #NoSQL #SQL #http头信息 #Llama-Factory # 大模型推理 #Coturn #TURN #ci/cd #k8s #log4j #Jetty # CosyVoice3 # 嵌入式服务器 #echarts #harmonyos #鸿蒙PC #GPU #AutoDL ##租显卡 #树莓派 #温湿度监控 #WhatsApp通知 #IoT #MySQL # 服务器IP # 端口7860 #pdf #建筑缺陷 #红外 #数据集 #结构体 #TCP服务器 #开发实战 #SMARC #ARM #全文检索 #银河麒麟服务器系统 #远程桌面 # 代理转发 # 跳板机 #Android16 #音频性能实战 #音频进阶 #短剧 #短剧小程序 #短剧系统 #微剧 #LangFlow # 智能运维 # 性能瓶颈分析 #空间计算 #原型模式 #hibernate #nosql #VibeVoice # 云服务器 #无人机 #戴尔服务器 #戴尔730 #装系统 #junit #新人首发 #汽车 #web服务器 #可撤销IBE #服务器辅助 #私钥更新 #安全性证明 #双线性Diffie-Hellman # 公钥认证 #Reactor #Kylin-Server #国产操作系统 #服务器安装 #clickhouse #代理 #企业开发 #ERP #项目实践 #.NET开发 #C#编程 #数据访问 #编程与数学 #I/O模型 #并发 #epoll #水平触发、边缘触发 #多路复用 #高级IO #sqlserver #eclipse #servlet #arm64 #CNAS #CMA #程序文件 #word #SSH复用 # 远程开发 #磁盘配额 #存储管理 #形考作业 #国家开放大学 #系统运维 #自动化运维 #IO #DHCP #网络安全大赛 #C++ UA Server #SDK #Windows #跨平台开发 #信息可视化 #云服务器选购 #Saas #CPU #线程 #散列表 #哈希算法 #机器视觉 #6D位姿 #UOS #海光K100 #统信 #outlook #错误代码2603 #无网络连接 #2603 #dba #mssql #数据安全 #注入漏洞 #wpf #实时检测 #卷积神经网络 #串口服务器 #Modbus #MOXA #GATT服务器 #蓝牙低功耗 #googlecloud #lucene #DAG #具身智能 #SSH密钥 #SSH公钥认证 # 安全加固 # ControlMaster #ETL管道 #RAG #向量存储 #数据预处理 #DocumentReader #硬件 #Fun-ASR # 语音识别 # WebUI #HarmonyOS APP #密码 #firefox #safari # RTX 3090 #jupyter #AI电商客服 #le audio #低功耗音频 #通信 #连接 #spring ai #oauth2 #数据可视化 #nmodbus4类库使用教程 #docker-compose #目标跟踪 #rtmp #PowerBI #企业 #windbg分析蓝屏教程 #fs7TF #c++20 #Buck #NVIDIA #算力 #交错并联 #DGX #ROS # 局域网访问 # 批量处理 #内存治理 #cosmic #IFix # 高温监控 # 远程连接 #gerrit #opc ua #opc #npu # 环境迁移 #大剑师 #nodejs面试题 #matplotlib #安全架构 #H5 #跨域 #发布上线后跨域报错 #请求接口跨域问题解决 #跨域请求代理配置 #request浏览器跨域 # 网络延迟 #系统升级 #信创 #指针 #anaconda #虚拟环境 #GB28181 #SIP信令 #SpringBoot #视频监控 #远程软件 #WT-2026-0001 #QVD-2026-4572 #smartermail #游戏机 # GLM-TTS # 数据安全 #xshell #host key #UDP的API使用 #TTS私有化 # IndexTTS # 音色克隆 #ESP32 # OTA升级 # 黄山派 #内网 #iBMC #UltraISO #设计师 #图像处理 #游戏美术 #技术美术 # Connection refused #系统管理 #服务 #teamviewer #视频 #代理服务器 #rsync # 数据同步 #ip #bash #arm开发 #Modbus-TCP #Apple AI #Apple 人工智能 #FoundationModel #Summarize #SwiftUI #LLM #大语言模型 #llama #ceph #ambari #arm #多线程 #claudeCode #content7 #跳槽 #工作 #挖矿 #Linux病毒 #sql注入 #网安应急响应 #odoo # GLM # 服务连通性 #azure #muduo库 # 高并发 #appche #数据恢复 #视频恢复 #视频修复 #RAID5恢复 #流媒体服务器恢复 #Ubuntu #aws #go # GPU集群 #Gateway #认证服务器集成详解 #服务器开启 TLS v1.2 #IISCrypto 使用教程 #TLS 协议配置 #IIS 安全设置 #服务器运维工具 #ftp #sftp #uniapp #合法域名校验出错 #服务器域名配置不生效 #request域名配置 #已经配置好了但还是报错 #uniapp微信小程序 #框架搭建 #YOLO识别 #YOLO环境搭建Windows #YOLO环境搭建Ubuntu #状态模式 #AI-native # 轻量化镜像 # 边缘计算 #Tokio #操作系统 #国产化OS #华为od #华为机试 #Java #OpenHarmony #springboot #知识库 #版本控制 #Git入门 #开发工具 #代码托管 #SSH跳转 #TTS #html5 #weston #x11 #x11显示服务器 #研发管理 #禅道 #禅道云端部署 #WinSCP 下载安装教程 #SFTP #FTP工具 #服务器文件传输 #计算几何 #斜率 #方向归一化 #叉积 #Ansible # 批量部署 #samba #RSO #机器人操作系统 #glibc #媒体 #远程连接 #cpu #rocketmq #套接字 #I/O多路复用 #字节序 #超算中心 #PBS #lsf #报表制作 #职场 #用数据讲故事 #手机h5网页浏览器 #安卓app #苹果ios APP #手机电脑开启摄像头并排查 #深度优先 #DFS #语音生成 #集成学习 #fabric #AI写作 #winscp #AI部署 # ms-swift #PN 结 #后端框架 #服务器线程 # SSL通信 # 动态结构体 #RWK35xx #语音流 #实时传输 #node #pxe #测评 #CCE #Dify-LLM #Flexus #lvs # 数字人系统 # 远程部署 # TURN # NAT穿透 #MCP服务器注解 #异步支持 #方法筛选 #声明式编程 #自动筛选机制 #前端框架 #嵌入式编译 #ccache #distcc #JNI #麦克风权限 #访问麦克风并录制音频 #麦克风录制音频后在线播放 #用户拒绝访问麦克风权限怎么办 #uniapp 安卓 苹果ios #将音频保存本地或上传服务器 #express #cherry studio #Node.js # child_process #free #vmstat #sar #KMS #slmgr #宝塔面板部署RustDesk #RustDesk远程控制手机 #手机远程控制 #铁路桥梁 #DIC技术 #箱梁试验 #裂纹监测 #四点弯曲 #rustdesk #可再生能源 #绿色算力 #风电 #spine #若依 #TRO #TRO侵权 #TRO和解 #运维工具 #GLM-4.6V-Flash-WEB # AI视觉 # 本地部署 #网络攻击模型 #进程 #进程创建与终止 #Discord机器人 #云部署 #程序那些事 #AI应用编程 # 自动化运维 #r语言 #mybatis #3d #服务器IO模型 #非阻塞轮询模型 #多任务并发模型 #异步信号模型 #多路复用模型 #系统安全 #ipmitool #BMC # 黑屏模式 # TTS服务器 #前端开发 #EN4FE #ollama #llm #领域驱动 #自由表达演说平台 #演说 #程序员创富 #移动端h5网页 #调用浏览器摄像头并拍照 #开启摄像头权限 #拍照后查看与上传服务器端 #摄像头黑屏打不开问题 #企业微信 #国产开源制品管理工具 #Hadess #一文上手 #蓝桥杯 #工业级串口服务器 #串口转以太网 #串口设备联网通讯模块 #串口服务器选型 #okhttp #embedding #IndexTTS2 # 阿里云安骑士 # 木马查杀 #范式 #入侵 #日志排查 #kmeans #聚类 #Karalon #AI Test #YOLOv8 # Docker镜像 #文件IO #输入输出流 #流程图 #论文阅读 #论文笔记 #图论 #人大金仓 #Kingbase #小艺 #鸿蒙 #搜索 #代理模式 #Spring AOP #程序人生 #健康医疗 #高考 #企业级存储 #网络设备 #iot #软件工程 #生信 #Smokeping #工程实践 #STDIO协议 #Streamable-HTTP #McpTool注解 #服务器能力 #策略模式 #pve #租显卡 #训练推理 #AI应用 #图像识别 #多进程 #python技巧 #pencil #pencil.dev #设计 #zotero #WebDAV #同步失败 #轻量化 #低配服务器 #Beidou #北斗 #SSR #Anything-LLM #IDC服务器 #私有化部署 #V11 #kylinos #大模型应用 #API调用 #PyInstaller打包运行 #服务端部署 #raid #raid阵列 #API #taro #java大文件上传 #java大文件秒传 #java大文件上传下载 #java文件传输解决方案 #wps #Linux多线程 #bigtop #hdp #hue #kerberos #PyCharm # 远程调试 # YOLOFuse #Playbook #AI服务器 #欧拉 #simulink #matlab #journalctl #aiohttp #asyncio #异步 #信息安全 #信息收集 #Langchain-Chatchat # 国产化服务器 # 信创 #软件 #本地生活 #电商系统 #商城 #poll # IndexTTS 2.0 #全链路优化 #实战教程 #database #idea #AI论文写作工具 #学术写作辅助 #论文创作效率提升 #AI写论文实测 #数字化转型 #实体经济 #商业模式 #软件开发 #数智红包 #商业变革 #创业干货 #AB包 #sglang #Go并发 #高并发架构 #Goroutine #系统设计 #Tracker 服务器 #响应最快 #torrent 下载 #2026年 #Aria2 可用 #迅雷可用 #BT工具通用 #交换机 #三层交换机 #SSH Agent Forwarding # 容器化 #高斯溅射 #UEFI #BIOS #Legacy BIOS #eBPF #云开发 #性能 #优化 #RAM #Harbor #AI智能棋盘 #Rock Pi S #边缘计算 #select #C/C++ #c++高并发 #百万并发 # 权限修复 #uip # HiChatBox # 离线AI #ui #SMTP # 内容安全 # Qwen3Guard #X11转发 #MinIO服务器启动与配置详解 #改行学it #平板 #零售 #智能硬件 #vncdotool #链接VNC服务器 #如何隐藏光标 #CTF #gateway #Comate #VMWare Tool #FHSS #Deepoc #具身模型 #开发板 #未来 #插件 #开源软件 #agent #ai大模型 #NFC #智能公交 #服务器计费 #FP-增长 #算力建设 #b树 #Proxmox VE #虚拟化 #memory mcp #Cursor #smtp #smtp服务器 #PHP #intellij idea #声源定位 #MUSIC # 远程访问 #Streamlit #AI聊天机器人 #tensorflow #memcache # 树莓派 # ARM架构 #银河麒麟操作系统 #openssh #华为交换机 #信创终端 #处理器 #飞牛nas #fnos #ansys #ansys问题解决办法 #分布式数据库 #集中式数据库 #业务需求 #选型误 #智能体对传统行业冲击 #行业转型 #雨云服务器 #Minecraft服务器 #教程 #MCSM面板 #Socket网络编程 #chat #HarmonyOS # 服务器配置 # GPU # 串口服务器 # NPort5630 #muduo #TcpServer #accept #高并发服务器 #Python办公自动化 #Python办公 #量子计算 #copilot #个人博客 #硬盘克隆 #DiskGenius # 键鼠锁定 #mtgsig #美团医药 #美团医药mtgsig #美团医药mtgsig1.2 #工程设计 #预混 #扩散 #燃烧知识 #层流 #湍流 #反向代理 #政务 #参数估计 #矩估计 #概率论 #adobe #powerbi #gmssh #宝塔 #1panel #Exchange #sentinel #系统安装 #MinIO #静脉曲张 #腿部健康 #运动 #POC #问答 #交付 #scikit-learn #随机森林 #Minecraft #PaperMC #我的世界服务器 #AI Agent #开发者工具 #jetty #kong #Kong Audio #Kong Audio3 #KongAudio3 #空音3 #空音 #中国民乐 #计算机外设 #边缘AI # Kontron # SMARC-sAMX8 #remote-ssh #SA-PEKS # 关键词猜测攻击 # 盲签名 # 限速机制 #scanf #printf #getchar #putchar #cin #cout #ET模式 #非阻塞 #多模态 #微调 #超参 #LLamafactory #产品经理 #就业 #OpenAI #故障 #vps #docker安装seata