国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【網(wǎng)絡(luò)編程】協(xié)議定制+Json序列化與反序列化

這篇具有很好參考價(jià)值的文章主要介紹了【網(wǎng)絡(luò)編程】協(xié)議定制+Json序列化與反序列化。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

【網(wǎng)絡(luò)編程】協(xié)議定制+Json序列化與反序列化


需要云服務(wù)器等云產(chǎn)品來學(xué)習(xí)Linux的同學(xué)可以移步/-->騰訊云<--/-->阿里云<--/-->華為云<--/官網(wǎng),輕量型云服務(wù)器低至112元/年,新用戶首次下單享超低折扣。


?目錄

一、序列化與反序列化的概念

二、自定義協(xié)議設(shè)計(jì)一個(gè)網(wǎng)絡(luò)計(jì)算器

2.1TCP協(xié)議,如何保證接收方收到了完整的報(bào)文呢?

2.2自定義協(xié)議的實(shí)現(xiàn)

2.3自定義協(xié)議在客戶端與服務(wù)器中的實(shí)現(xiàn)

三、使用Json進(jìn)行序列化和反序列化

3.1jsoncpp庫的安裝

3.2改造自定義協(xié)議

3.3自定義協(xié)議的命名區(qū)分


網(wǎng)絡(luò)版計(jì)算器代碼可參考博主gitee。

一、序列化與反序列化的概念

????????序列化是指將對(duì)象轉(zhuǎn)換為字節(jié)流或其他可存儲(chǔ)或傳輸?shù)母袷剑员銓⑵浯鎯?chǔ)在文件中或通過網(wǎng)絡(luò)發(fā)送到另一個(gè)系統(tǒng)。反序列化是指將序列化的數(shù)據(jù)重新轉(zhuǎn)換為對(duì)象。在序列化和反序列化過程中,對(duì)象的狀態(tài)信息被保存和恢復(fù),以保證數(shù)據(jù)的完整性和正確性。在分布式系統(tǒng)中,序列化和反序列化是實(shí)現(xiàn)遠(yuǎn)程方法調(diào)用和消息傳遞的重要技術(shù)。

????????例如微信發(fā)送一條消息,會(huì)將頭像、昵稱、消息內(nèi)容、發(fā)送時(shí)間等“結(jié)構(gòu)化”數(shù)據(jù)進(jìn)行序列化,形成一個(gè)字節(jié)流報(bào)文,通過網(wǎng)絡(luò)將該報(bào)文發(fā)送給接收方,接收方進(jìn)行反序列化將報(bào)文重新拆解為頭像、昵稱、消息內(nèi)容、發(fā)送時(shí)間等“結(jié)構(gòu)化”數(shù)據(jù)。

【網(wǎng)絡(luò)編程】協(xié)議定制+Json序列化與反序列化

二、自定義協(xié)議設(shè)計(jì)一個(gè)網(wǎng)絡(luò)計(jì)算器

2.1TCP協(xié)議,如何保證接收方收到了完整的報(bào)文呢?

【網(wǎng)絡(luò)編程】協(xié)議定制+Json序列化與反序列化

1、我們調(diào)用的所有發(fā)送/接收函數(shù),并不是直接從網(wǎng)絡(luò)中發(fā)送/接收數(shù)據(jù),應(yīng)用層調(diào)用的發(fā)送/接收函數(shù),本質(zhì)是一個(gè)拷貝函數(shù)。
例如客戶端發(fā)送數(shù)據(jù)時(shí),應(yīng)用層調(diào)用發(fā)送函數(shù)將會(huì)把應(yīng)用層的發(fā)送緩沖區(qū)數(shù)據(jù)拷貝至傳輸層的發(fā)送緩沖區(qū)。傳輸層自主決定何時(shí)將發(fā)送緩沖區(qū)的數(shù)據(jù)發(fā)送至網(wǎng)絡(luò)里,再通過網(wǎng)絡(luò)發(fā)送至服務(wù)器的接收緩沖區(qū)中,所以TCP協(xié)議是一種傳輸控制協(xié)議。

2、TCP協(xié)議的通信雙方的發(fā)送緩沖區(qū)和接收緩沖區(qū)互不干擾,可以雙向同時(shí)進(jìn)行通信。TCP是一種全雙工的通信協(xié)議。

3、如果TCP服務(wù)器的讀取速度跟不上客戶端的發(fā)送速度,將會(huì)導(dǎo)致服務(wù)器接收緩沖區(qū)積攢大量的報(bào)文,這些報(bào)文數(shù)據(jù)可是一連串的粘連在一起的,如何一條一條的將完整的報(bào)文提取出來呢?使用協(xié)議!協(xié)議設(shè)計(jì)方式:

  • 定長(例如規(guī)定該報(bào)文定長為1024字節(jié))
  • 特殊符號(hào)(在報(bào)文和報(bào)文之間增加特殊符號(hào))
  • 自描述方式(自己設(shè)計(jì)協(xié)議)

本文代碼協(xié)議設(shè)計(jì)如下圖所示:使用該協(xié)議設(shè)計(jì)一個(gè)網(wǎng)絡(luò)計(jì)算器。

【網(wǎng)絡(luò)編程】協(xié)議定制+Json序列化與反序列化

????????如果是UDP協(xié)議,UDP客戶端,發(fā)送報(bào)文時(shí)只需創(chuàng)建請(qǐng)求,對(duì)請(qǐng)求進(jìn)行序列化后即可發(fā)送;接收?qǐng)?bào)文時(shí)只需將接收的數(shù)據(jù)進(jìn)行反序列化即可。無需進(jìn)行協(xié)議內(nèi)容的添加與解析。這是因?yàn)閁DP每次發(fā)送與接收都是以數(shù)據(jù)報(bào)的形式,數(shù)據(jù)是完整的,不像TCP是面向字節(jié)流,需要使用相關(guān)的協(xié)議進(jìn)行界定報(bào)文邊界。

2.2自定義協(xié)議的實(shí)現(xiàn)

#pragma once
#include <iostream>
#include <string>
#include <vector>
#include <cstring>
enum
{
    OK=0,
    DIV_ZERO_ERR,
    MOD_ZERO_ERR,
    OP_ZERO_ERR,
};
#define SEP " "
#define SEP_LEN strlen(SEP)//不能使用sizeof,用sizeof會(huì)統(tǒng)計(jì)到'\0'
#define LINE_SEP "\r\n"
#define LINE_SEP_LINE strlen(LINE_SEP)
//"_exitcode result" -> "content_len"\r\n"_exitcode result"\r\n
//"_x _op _y" -> "content_len"\r\n"_x _op _y"\r\n
std::string enLength(const std::string& text)//text:_x _op _y。添加協(xié)議規(guī)則,用于構(gòu)建一個(gè)完整的報(bào)文(類似"打包")
{
    std::string send_string=std::to_string(text.size());//計(jì)算有效載荷的長度"_x _op _y"
    send_string+=LINE_SEP;
    send_string+=text;
    send_string+=LINE_SEP;
    return send_string;
}
//_exitcode result
bool deLength(const std::string& package,std::string* text)//獲取報(bào)文中的有效載荷(類似"解包")
{
    auto pos=package.find(LINE_SEP);
    if(pos==std::string::npos){return false;}
    int textLen=std::stoi(package.substr(0,pos));//計(jì)算有效載荷的長度
    *text=package.substr(pos+LINE_SEP_LINE,textLen);
    return true;
}
class Request//請(qǐng)求類
{
public:
    Request(int x,int y,char op)
        :_x(x)
        ,_y(y)
        ,_op(op)
    {}
    Request()
        :_x(0)
        ,_y(0)
        ,_op(0)
    {}
    bool serialize(std::string* out)//序列化,將成員變量轉(zhuǎn)字符串
    {
        //結(jié)構(gòu)化->"_x _op _y"
        *out="";//清空string對(duì)象
        std::string x_tostring=std::to_string(_x);
        std::string y_tostring=std::to_string(_y);
        *out=x_tostring+SEP+_op+SEP+y_tostring;//_x _op _y
        return true;
    }
    bool deserialize(const std::string& in)//反序列化
    {
        //"_x _op _y"->結(jié)構(gòu)化
        auto leftSpace=in.find(SEP);//左邊的空格
        auto rightSpace=in.rfind(SEP);//右邊的空格
        if(leftSpace==std::string::npos||rightSpace==std::string::npos){return false;}
        if(leftSpace==rightSpace){return false;} 
        //子串提取
        std::string x_tostring=in.substr(0,leftSpace);
        if(rightSpace-(leftSpace+SEP_LEN)!=1){return false;}//表示操作符一定只占1位
        _op=in.substr(leftSpace+SEP_LEN,rightSpace-(leftSpace+SEP_LEN))[0];
        std::string y_tostring=in.substr(rightSpace+SEP_LEN);
        //對(duì)x,y進(jìn)行轉(zhuǎn)換
        _x=std::stoi(x_tostring); 
        _y=std::stoi(y_tostring);
        return true;
    }
public:
    //_x _op _y
    int _x;//左操作數(shù)
    int _y;//右操作數(shù)
    char _op;//操作符
};

class Response//響應(yīng)類
{
public:
    Response()
        :_exitCode(0)
        ,_result(0)
    {}
    Response(int exitCode,int result)
        :_exitCode(exitCode)
        ,_result(result)
    {}
    bool serialize(std::string* out)//序列化,將成員變量轉(zhuǎn)string對(duì)象
    {
        *out="";//清空string對(duì)象
        std::string outString=std::to_string(_exitCode)+SEP+std::to_string(_result);
        *out=outString;
        return true; 
    }
    bool deserialize(const std::string& in)//反序列化
    {
        auto space=in.find(SEP);//找空格
        if(space==std::string::npos){return false;}
        std::string exitString=in.substr(0,space);
        std::string resString=in.substr(space+SEP_LEN);
        if(exitString.empty()||resString.empty()){return false;}//一個(gè)字符串為空就false
        _exitCode=std::stoi(exitString);
        _result=std::stoi(resString);
        return true;
    }
public:
    int _exitCode;//0表示計(jì)算成功,非零代表除零等錯(cuò)誤
    int _result;//運(yùn)算結(jié)果
};

bool recvPackage(int sock,std::string& inbuffer,std::string* text)//服務(wù)器/客戶端讀取報(bào)文
{
    //將緩沖區(qū)數(shù)據(jù)拆分成一個(gè)個(gè)報(bào)文"content_len"\r\n"_x _op _y"\r\n
    char buffer[1024];
    while(1)
    {
        ssize_t n=recv(sock,buffer,sizeof(buffer)-1,0);//阻塞式讀取,等價(jià)于read接口
        if(n>0)
        {
            buffer[n]=0;//字符串末尾添加'\0'
            inbuffer+=buffer;
            //拆分成一個(gè)個(gè)報(bào)文
            auto pos=inbuffer.find(LINE_SEP);//找\r\n的起始位置
            if(pos==std::string::npos)//沒找到說明暫時(shí)還沒找到\r\n分隔符,跳過本次循環(huán),等待下次讀取
            {
                continue;
            }
            std::string textLenString=inbuffer.substr(0,pos);
            int textLen=std::stoi(textLenString);//拿出有效載荷的長度
            int totalLen=textLenString.size()+2*LINE_SEP_LINE+textLen;//單個(gè)報(bào)文總長度
            if(inbuffer.size()<totalLen)//說明緩沖區(qū)長度還不到一個(gè)報(bào)文大小,需要跳過本次循環(huán)繼續(xù)讀取
            {
                continue;
            }
            std::cout<<"截取報(bào)文前inbuffer中的內(nèi)容:\n"<<inbuffer<<std::endl;
            //走到這里,一定有一個(gè)完整的報(bào)文
            *text=inbuffer.substr(0,totalLen);//取出一個(gè)報(bào)文
            inbuffer.erase(0,totalLen);//刪掉緩沖區(qū)中剛剛被提取走的報(bào)文數(shù)據(jù)
            std::cout<<"截取報(bào)文后inbuffer中的內(nèi)容:\n"<<inbuffer<<std::endl;
            break;
        }
        else
        {
            return false;
        }
    }
    return true;
}

代碼解釋:

本協(xié)議設(shè)計(jì)了一個(gè)Request請(qǐng)求類和一個(gè)Response響應(yīng)類,請(qǐng)求類存儲(chǔ)計(jì)算器的操作數(shù)和操作符,響應(yīng)類存儲(chǔ)計(jì)算結(jié)果和退出碼。這兩個(gè)類中各自實(shí)現(xiàn)了對(duì)有效載荷的序列化與反序列化的接口。

enLength用于給有效載荷添加報(bào)頭,即自定義協(xié)議的規(guī)則。deLength則用于解析收到的報(bào)文,剔除報(bào)文中的協(xié)議報(bào)頭,提取出其中的有效載荷。協(xié)議是明確緩沖區(qū)中報(bào)文與報(bào)文之間邊界的一種特殊格式,而enLength和deLength用于添加報(bào)頭和去掉報(bào)頭。

2.3自定義協(xié)議在客戶端與服務(wù)器中的實(shí)現(xiàn)

【網(wǎng)絡(luò)編程】協(xié)議定制+Json序列化與反序列化

三、使用Json進(jìn)行序列化和反序列化

3.1jsoncpp庫的安裝

????????從上方代碼可以看到,使用string對(duì)象手動(dòng)進(jìn)行序列化與反序列化非常麻煩??梢允褂肑son進(jìn)行序列化與反序列化操作。

????????Json(JavaScript Object Notation)是一種輕量級(jí)的數(shù)據(jù)交換格式,常用于Web應(yīng)用程序中的數(shù)據(jù)傳輸。它是一種基于文本的格式,易于讀寫和解析。Json格式的數(shù)據(jù)可以被多種編程語言支持,包括JavaScript、Python、Java、C#、C++等。Json數(shù)據(jù)由鍵值對(duì)組成,使用大括號(hào)表示對(duì)象,使用方括號(hào)表示數(shù)組。

【網(wǎng)絡(luò)編程】協(xié)議定制+Json序列化與反序列化

????????C++使用Json需要包含Jsoncpp庫,yum安裝Jsoncpp庫指令:先執(zhí)行第二句,如果報(bào)錯(cuò)再執(zhí)行第一句!

sudo mv /var/lib/rpm/__db.00* /tmp/&&yum clean all
sudo yum install -y jsoncpp-devel

3.2改造自定義協(xié)議

makefile:使用jsoncpp庫記得在編譯時(shí)加上-ljsoncpp

cc=g++#將cc變量設(shè)置為g++編譯器
LD=#-DMYSELF
.PHONY:all
all:calClient calServer

calClient:calClient.cc
	$(cc) -o $@ $^ -std=c++11 -ljsoncpp ${LD}
calServer:calServer.cc
	$(cc) -o $@ $^ -std=c++11 -ljsoncpp ${LD}
	
.PHONY:clean
clean:
	rm -f calClient calServer

改造的協(xié)議:?

#pragma once
#include <iostream>
#include <string>
#include <vector>
#include <cstring>
#include <jsoncpp/json/json.h>
#include <sys/types.h>
#include <sys/socket.h>
enum
{
    OK=0,
    DIV_ZERO_ERR,
    MOD_ZERO_ERR,
    OP_ZERO_ERR,
};
#define SEP " "
#define SEP_LEN strlen(SEP)//不能使用sizeof,用sizeof會(huì)統(tǒng)計(jì)到'\0'
#define LINE_SEP "\r\n"
#define LINE_SEP_LINE strlen(LINE_SEP)
//"_exitcode result" -> "content_len"\r\n"_exitcode result"\r\n
//"_x _op _y" -> "content_len"\r\n"_x _op _y"\r\n
std::string enLength(const std::string& text)//text:_x _op _y。添加協(xié)議規(guī)則,用于構(gòu)建一個(gè)完整的報(bào)文(類似"打包")
{
    std::string send_string=std::to_string(text.size());//計(jì)算有效載荷的長度"_x _op _y"
    send_string+=LINE_SEP;
    send_string+=text;
    send_string+=LINE_SEP;
    return send_string;
}
//_exitcode result
bool deLength(const std::string& package,std::string* text)//獲取報(bào)文中的有效載荷(類似"解包")
{
    auto pos=package.find(LINE_SEP);
    if(pos==std::string::npos){return false;}
    int textLen=std::stoi(package.substr(0,pos));//計(jì)算有效載荷的長度
    *text=package.substr(pos+LINE_SEP_LINE,textLen);
    return true;
}
class Request//請(qǐng)求類
{
public:
    Request(int x,int y,char op)
        :_x(x)
        ,_y(y)
        ,_op(op)
    {}
    Request()
        :_x(0)
        ,_y(0)
        ,_op(0)
    {}
    bool serialize(std::string* out)//序列化,將成員變量轉(zhuǎn)字符串
    {
#ifdef MYSELF
        //結(jié)構(gòu)化->"_x _op _y"
        *out="";//清空string對(duì)象
        std::string x_tostring=std::to_string(_x);
        std::string y_tostring=std::to_string(_y);
        *out=x_tostring+SEP+_op+SEP+y_tostring;//_x _op _y
#else
        //Json序列化
        Json::Value root;//Json::Value萬能對(duì)象,可接收任何對(duì)象
        root["first"]=_x;//自動(dòng)將_x轉(zhuǎn)換為字符串
        root["second"]=_y;
        root["oper"]=_op;
        //序列化
        Json::FastWriter writer;//Json::StyledWriter write;等價(jià)
        *out=writer.write(root);//將root進(jìn)行序列化,返回值為string對(duì)象,接收即可
#endif
        return true;
    }
    bool deserialize(const std::string& in)//反序列化
    {
#ifdef MYSELF
        //"_x _op _y"->結(jié)構(gòu)化
        auto leftSpace=in.find(SEP);//左邊的空格
        auto rightSpace=in.rfind(SEP);//右邊的空格
        if(leftSpace==std::string::npos||rightSpace==std::string::npos){return false;}
        if(leftSpace==rightSpace){return false;} 
        //子串提取
        std::string x_tostring=in.substr(0,leftSpace);
        if(rightSpace-(leftSpace+SEP_LEN)!=1){return false;}//表示操作符一定只占1位
        _op=in.substr(leftSpace+SEP_LEN,rightSpace-(leftSpace+SEP_LEN))[0];
        std::string y_tostring=in.substr(rightSpace+SEP_LEN);
        //對(duì)x,y進(jìn)行轉(zhuǎn)換
        _x=std::stoi(x_tostring); 
        _y=std::stoi(y_tostring);
#else
        //Json反序列化
        Json::Value root;//Json::Value萬能對(duì)象,可接收任何對(duì)象
        Json::Reader reader;
        reader.parse(in,root);//第一個(gè)參數(shù):解析哪個(gè)流;第二個(gè)參數(shù):將解析的數(shù)據(jù)存放到對(duì)象中
        //反序列化
        _x=root["first"].asInt();//默認(rèn)是字符串,轉(zhuǎn)換為整型
        _y=root["second"].asInt();
        _op=root["oper"].asInt();//轉(zhuǎn)換為整型,整型可以給char類型。
#endif
        return true;
    }
public:
    //_x _op _y
    int _x;//左操作數(shù)
    int _y;//右操作數(shù)
    char _op;//操作符
};

class Response//響應(yīng)類
{
public:
    Response()
        :_exitCode(0)
        ,_result(0)
    {}
    Response(int exitCode,int result)
        :_exitCode(exitCode)
        ,_result(result)
    {}
    bool serialize(std::string* out)//序列化,將成員變量轉(zhuǎn)string對(duì)象
    {
#ifdef MYSELF
        *out="";//清空string對(duì)象
        std::string outString=std::to_string(_exitCode)+SEP+std::to_string(_result);
        *out=outString;
#else
        //Json序列化
        Json::Value root;//Json::Value萬能對(duì)象,可接收任何對(duì)象
        root["exitCode"]=_exitCode;//自動(dòng)將_exitCode轉(zhuǎn)換為字符串
        root["result"]=_result;
        //序列化
        Json::FastWriter writer;//Json::StyledWriter write;等價(jià)
        *out=writer.write(root);//將root進(jìn)行序列化,返回值為string對(duì)象,接收即可
#endif
        return true; 
    }
    bool deserialize(const std::string& in)//反序列化
    {
#ifdef MYSELF
        auto space=in.find(SEP);//找空格
        if(space==std::string::npos){return false;}
        std::string exitString=in.substr(0,space);
        std::string resString=in.substr(space+SEP_LEN);
        if(exitString.empty()||resString.empty()){return false;}//一個(gè)字符串為空就false
        _exitCode=std::stoi(exitString);
        _result=std::stoi(resString);
#else
        //Json反序列化
        Json::Value root;//Json::Value萬能對(duì)象,可接收任何對(duì)象
        Json::Reader reader;
        reader.parse(in,root);//第一個(gè)參數(shù):解析哪個(gè)流;第二個(gè)參數(shù):將解析的數(shù)據(jù)存放到對(duì)象中
        //反序列化
        _exitCode=root["exitCode"].asInt();//默認(rèn)是字符串,轉(zhuǎn)換為整型
        _result=root["result"].asInt();
#endif
        return true;
    }
public:
    int _exitCode;//0表示計(jì)算成功,非零代表除零等錯(cuò)誤
    int _result;//運(yùn)算結(jié)果
};

bool recvPackage(int sock,std::string& inbuffer,std::string* text)//服務(wù)器/客戶端讀取報(bào)文
{
    //將緩沖區(qū)數(shù)據(jù)拆分成一個(gè)個(gè)報(bào)文"content_len"\r\n"_x _op _y"\r\n
    char buffer[1024];
    while(1)
    {
        ssize_t n=recv(sock,buffer,sizeof(buffer)-1,0);//阻塞式讀取,等價(jià)于read接口
        if(n>0)
        {
            buffer[n]=0;//字符串末尾添加'\0'
            inbuffer+=buffer;
            //拆分成一個(gè)個(gè)報(bào)文
            auto pos=inbuffer.find(LINE_SEP);//找\r\n的起始位置
            if(pos==std::string::npos)//沒找到說明暫時(shí)還沒找到\r\n分隔符,跳過本次循環(huán),等待下次讀取
            {
                continue;
            }
            std::string textLenString=inbuffer.substr(0,pos);
            int textLen=std::stoi(textLenString);//拿出有效載荷的長度
            int totalLen=textLenString.size()+2*LINE_SEP_LINE+textLen;//單個(gè)報(bào)文總長度
            if(inbuffer.size()<totalLen)//說明緩沖區(qū)長度還不到一個(gè)報(bào)文大小,需要跳過本次循環(huán)繼續(xù)讀取
            {
                continue;
            }
            std::cout<<"截取報(bào)文前inbuffer中的內(nèi)容:\n"<<inbuffer<<std::endl;
            //走到這里,一定有一個(gè)完整的報(bào)文
            *text=inbuffer.substr(0,totalLen);//取出一個(gè)報(bào)文
            inbuffer.erase(0,totalLen);//刪掉緩沖區(qū)中剛剛被提取走的報(bào)文數(shù)據(jù)
            std::cout<<"截取報(bào)文后inbuffer中的內(nèi)容:\n"<<inbuffer<<std::endl;
            break;
        }
        else
        {
            return false;
        }
    }
    return true;
}
bool recvPackageAll(int sock,std::string& inbuffer,std::vector<std::string>* out)
{
    std::string line; 
    while(recvPackage(sock,inbuffer,&line))
    {
        out->push_back(line);
    }
}

3.3自定義協(xié)議的命名區(qū)分

????????未來在一套系統(tǒng)中可以自定義多種協(xié)議,為了區(qū)分不同的自定義協(xié)議,可以參照如下格式設(shè)計(jì)協(xié)議的格式:

【網(wǎng)絡(luò)編程】協(xié)議定制+Json序列化與反序列化

當(dāng)然前人已經(jīng)設(shè)計(jì)好了常見的網(wǎng)絡(luò)協(xié)議,例如http/https。

【網(wǎng)絡(luò)編程】協(xié)議定制+Json序列化與反序列化文章來源地址http://www.zghlxwxcb.cn/news/detail-461929.html

到了這里,關(guān)于【網(wǎng)絡(luò)編程】協(xié)議定制+Json序列化與反序列化的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 協(xié)議定制 + Json序列化反序列化

    協(xié)議定制 + Json序列化反序列化

    1.1 結(jié)構(gòu)化數(shù)據(jù) 協(xié)議是一種 “約定”,socket api的接口, 在讀寫數(shù)據(jù)時(shí),都是按 “字符串” 的方式來發(fā)送接收的。如果我們要傳輸一些\\\"結(jié)構(gòu)化的數(shù)據(jù)\\\" 怎么辦呢? 結(jié)構(gòu)化數(shù)據(jù): 比如我們?cè)赒Q聊天時(shí),并不是單純地只發(fā)送了消息本身,是把自己的頭像、昵稱、發(fā)送時(shí)間、消息本身

    2024年02月09日
    瀏覽(26)
  • 【網(wǎng)絡(luò)】協(xié)議定制+序列化/反序列化

    【網(wǎng)絡(luò)】協(xié)議定制+序列化/反序列化

    如果光看定義很難理解序列化的意義,那么我們可以從另一個(gè)角度來推導(dǎo)出什么是序列化, 那么究竟序列化的目的是什么? 其實(shí)序列化最終的目的是為了對(duì)象可以 跨平臺(tái)存儲(chǔ),和進(jìn)行網(wǎng)絡(luò)傳輸 。而我們進(jìn)行跨平臺(tái)存儲(chǔ)和網(wǎng)絡(luò)傳輸?shù)姆绞骄褪荌O,而我們的IO支持的數(shù)據(jù)格式就是

    2024年02月08日
    瀏覽(21)
  • 【網(wǎng)絡(luò)】應(yīng)用層——協(xié)議定制 | 序列化和反序列化 | 初識(shí)http

    【網(wǎng)絡(luò)】應(yīng)用層——協(xié)議定制 | 序列化和反序列化 | 初識(shí)http

    ??作者:一只大喵咪1201 ??專欄:《網(wǎng)絡(luò)》 ??格言: 你只管努力,剩下的交給時(shí)間! 在前面本喵已經(jīng)帶大家見識(shí)過了 scoket 網(wǎng)絡(luò)通信的樣子,現(xiàn)在開始深入學(xué)習(xí)網(wǎng)絡(luò)的原理,本喵采取的策略是從頂層往底層講解,也就是從應(yīng)用層到數(shù)據(jù)鏈路層的順序。 我們知道,協(xié)議就是

    2024年02月15日
    瀏覽(28)
  • TCP定制協(xié)議,序列化和反序列化

    TCP定制協(xié)議,序列化和反序列化

    目錄 前言 1.理解協(xié)議 2.網(wǎng)絡(luò)版本計(jì)算器 2.1設(shè)計(jì)思路 2.2接口設(shè)計(jì) 2.3代碼實(shí)現(xiàn): 2.4編譯測試 總結(jié) ? ? ? ? 在之前的文章中,我們說TCP是面向字節(jié)流的,但是可能對(duì)于面向字節(jié)流這個(gè)概念,其實(shí)并不理解的,今天我們要介紹的是如何理解TCP是面向字節(jié)流的,通過編碼的方式,自

    2024年02月12日
    瀏覽(22)
  • 【Linux后端服務(wù)器開發(fā)】協(xié)議定制(序列化與反序列化)

    【Linux后端服務(wù)器開發(fā)】協(xié)議定制(序列化與反序列化)

    目錄 一、應(yīng)用層協(xié)議概述 二、序列化與反序列化 Protocal.h頭文件 Server.h頭文件 Client.h頭文件 server.cpp源文件 client.cpp源文件 什么是應(yīng)用層 ?我們通過編寫程序解決一個(gè)個(gè)實(shí)際問題、滿足我們?nèi)粘P枨蟮木W(wǎng)絡(luò)程序,都是應(yīng)用層程序。 協(xié)議是一種“約定”,socket的api接口,在讀

    2024年02月16日
    瀏覽(21)
  • 協(xié)議,序列化,反序列化,Json

    協(xié)議,序列化,反序列化,Json

    協(xié)議究竟是什么呢?首先得知道主機(jī)之間的網(wǎng)絡(luò)通信交互的是什么數(shù)據(jù),像平時(shí)使用聊天APP聊天可以清楚,用戶看到的不僅僅是聊天的文字,還能夠看到用戶的頭像昵稱等其他屬性。也就可以證明網(wǎng)絡(luò)通信不僅僅是交互字符串那么簡單。事實(shí)上網(wǎng)絡(luò)通信還可能會(huì)通過一個(gè)結(jié)構(gòu)

    2024年02月13日
    瀏覽(24)
  • 序列化協(xié)議:JSON和XML

    作者:CARROT 鏈接:https://www.zhihu.com/question/604811576/answer/3100483698 來源:知乎 著作權(quán)歸作者所有。商業(yè)轉(zhuǎn)載請(qǐng)聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請(qǐng)注明出處。 ? json和xml都是數(shù)據(jù)傳輸?shù)母袷?。比如我們開發(fā)過程中需要和網(wǎng)頁交換數(shù)據(jù),我們既可以使用json格式也可以使用xml格式。再

    2024年02月11日
    瀏覽(19)
  • 【Linux】簡單的網(wǎng)絡(luò)計(jì)算器的實(shí)現(xiàn)(自定義協(xié)議,序列化,反序列化)

    【Linux】簡單的網(wǎng)絡(luò)計(jì)算器的實(shí)現(xiàn)(自定義協(xié)議,序列化,反序列化)

    我們需要實(shí)現(xiàn)一個(gè)服務(wù)器版的加法器. 我們需要客戶端把要計(jì)算的兩個(gè)加數(shù)發(fā)過去, 然后由服務(wù)器進(jìn)行計(jì)算, 最后再把結(jié)果返回給客戶端` 詳細(xì)可參考我之前寫的博客【Linux】記錄錯(cuò)誤信息日志的實(shí)現(xiàn)

    2024年02月19日
    瀏覽(29)
  • Android網(wǎng)絡(luò)編程,HTTP請(qǐng)求和Json解析

    以下代碼模擬了點(diǎn)擊按鈕請(qǐng)求百度的網(wǎng)頁源碼: 其中需要注意的是Android在API27之后不再支持明文訪問HTTP,需要在manifest文件中配置屬性允許使用明文訪問, 并且Url需要使用https layout.xml 字節(jié)流轉(zhuǎn)換字符串工具類: 主類.java: 配置manifest.xml文件: 將上述代碼中的webview相關(guān)內(nèi)容

    2023年04月09日
    瀏覽(28)
  • 【網(wǎng)絡(luò)編程】網(wǎng)絡(luò)層——IP協(xié)議

    【網(wǎng)絡(luò)編程】網(wǎng)絡(luò)層——IP協(xié)議

    TCP作為傳輸層控制協(xié)議,其保證的是數(shù)據(jù)傳輸?shù)目煽啃院蛡鬏斝?,但TCP提供的僅僅是數(shù)據(jù)傳輸?shù)牟呗?,而真正?fù)責(zé)數(shù)據(jù)在網(wǎng)絡(luò)中傳輸?shù)钠鋵?shí)是傳輸層以下的網(wǎng)絡(luò)層和數(shù)據(jù)鏈路層。 雙方在進(jìn)行網(wǎng)絡(luò)通信時(shí),發(fā)送的數(shù)據(jù)并不是直接從一方的傳輸層直接發(fā)送到了另一方的傳輸層,

    2024年02月05日
    瀏覽(30)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包