自定义协议的网络计算器项目

源码链接:NetworkComputer_CustomProtocol_V3 · 周不才/cpp_linux study - 码云 - 开源中国

自定义协议(添加/去除报头,序列化/反序列化)Custom.hpp:

//自定义协议:包含自定义格式的序列化和反序列化、添加报头、去除报头操作
#pragma once
#include <iostream>
#include <string>
#include <jsoncpp/json/json.h>
#include <memory>//提供智能指针
#include "Log.hpp"//日志

using namespace log_ns;

//自定义协议约定:
//添加报头时为json子串加上有效载荷长度len和\r\n
//即 "len"\r\n{json}\r\n

static const std::string sep="\r\n";

//添加报头
std::string Encode(const std::string& jsonstr)
{
    //参数说明:jsonstr是不带报头json字符串
    //返回值:返回添加报头后的json字符串

    size_t len=jsonstr.size();
    std::string packagejsonstr=std::to_string(len)+sep+jsonstr+sep;//带报头的json字符串
    return packagejsonstr;
}

//去除报头
std::string Decode(std::string& packagejsonstr)
{
    //参数说明:jsonstr是带报头的json字符串
    //返回值:返回去除报头后的json字符串

    size_t pos=packagejsonstr.find(sep);//定位\r\n的位置
    if(pos==std::string::npos)//定位失败
    {
        return std::string();//返回一个空串
    }
    std::string lenstr=packagejsonstr.substr(0,pos);//取出"len"
    int len=std::stoi(lenstr);//json字符串长度

    
    int total=lenstr.size()+len+sep.size()*2;//计算完整的报文长度,即"len"\r\n{json}\r\n长度
    if(packagejsonstr.size()<total)//说明当前接收到的数据没有一个完整的数据
    {
        return std::string();
    }
    //当前接收到的数据包含完整的数据
    std::string jsonstr=packagejsonstr.substr(pos+sep.size(),len);//开始提取有效数据(即json字符串)
    packagejsonstr.erase(0,total);//删除已经提取到的数据
    return jsonstr;
}   

//请求类Request:服务端处理数据之前,数据的格式
class Request
{
private:
    int _x;
    int _y;
    char _operator;
public:
    //初始化Request数据
    void SetValue(int x,int y,char op)
    {
        _x=x;
        _y=y;
        _operator=op;
    }
    //获取数据
    int GetX()
    {
        return _x;
    }
    int GetY()
    {
        return _y;
    }
    char Getoperator()
    {
        return _operator;
    }
public:

    //序列化操作
    bool Serialize(std::string* out)
    {
        //参数说明
        //out是输出型参数,用于带出序列化为json字符串格式的数据

        //先将Request对象转换为Json::Value类型
        Json::Value root;
        root["x"]=_x;
        root["y"]=_y;
        root["operator"]=_operator;
        //再将Json::Value类型转换为json字符串类型
        *out=root.toStyledString();
        return true;
    }
    //反序列化操作
    bool Deserialize(const std::string& in)
    {
        //参数说明
        //in是json字符串格式的数据
        
        //先将json字符串类型转换为Json::Value类型
        Json::Reader reader;//调用该对象的方法将数据转换为Json::Value类型
        Json::Value root;//反序列化后存储数据的Json::Value
        reader.parse(in,root);//将数据转换为Json::Value类型

        //再将Json::Value类型转换为Request对象
        _x=root["x"].asInt();
        _y=root["y"].asInt();
        _operator=root["operator"].asInt();
        return true;
    }
};

//应答类Response:服务端处理数据之后,数据的格式
class Response
{
private:
    int _result;//运算结果
    int _code;//运算结果码(0表示正常,1表示除0操作,2表示其他非法操作)
    std::string _describe;//运算结果描述
public:
    //输出结果
    void Result()
    {
        std::cout<<"result: "<<_result<<", code: "<<_code<<", describe: "<<_describe<<std::endl;
    }
    //设置数据
    void SetResult(int result)
    {
        _result=result;
    }
    void SetCode(int code)
    {
        _code=code;
    }
    void SetDescribe(std::string describe)
    {
        _describe=describe;
    }
public:
    //序列化操作
    bool Serialize(std::string* out)
    {
        //先将Response对象转换为Json::Value类型
        Json::Value root;
        root["result"]=_result;
        root["code"]=_code;
        root["describe"]=_describe;
        //再将Json::Value类型转换为json字符串类型
        *out=root.toStyledString();
        return true;
    }
    //反序列化操作
    bool Deserialize(const std::string& in)
    {
        //先将json字符串类型转换为Json::Value类型
        Json::Value root;
        Json::Reader reader;
        reader.parse(in,root);
        //再将Json::Value类型转换为Response对象
        _result=root["result"].asInt();
        _code=root["code"].asInt();
        _describe=root["describe"].asString();
        return true;
    }
};

//工厂模式:调用函数直接返回Request对象和Response对象
class Factory
{
public:
    //构建Request对象
    static std::shared_ptr<Request> BuildRequest()
    {
        return std::make_shared<Request>();
    }
    //构建Response对象
    static std::shared_ptr<Response> BuildResponse()
    {
        return std::make_shared<Response>();
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

南林yan

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值