网络版本计算器:自定义协议层

在网络版本计算器中应用层需要我们自定义一个协议层
一个协议层需要有请求报文,应答报文,提取报文,判断报文完整性,处理交给业务层

点击查看代码
#ifndef __PROTOCL_HPP
#define __PROTOCL_HPP
#include <iostream>
#include "Log.hpp"
#include <string>
#include <jsoncpp/json/json.h>
#include <functional>
#include<memory>
using namespace LogModule;
//协议层
//请求报文
class Request
{
public:
    Request()
    {
    }
    Request(int x, int y, char oper) : _x(x), _y(y), _oper(oper)
    {
    }
    void Serialise(std::string *outstr)
    {
        // 序列化
        Json::Value root;
        root["datax"] = _x;
        root["datay"] = _y;
        root["oper"] = _oper;
        Json::FastWriter writer;
        *outstr = writer.write(root);
    }
    void Deserialise(std::string &instr)//反序列化服务端处理
    {
        Json::Value root;
        Json::Reader reader;
        if (reader.parse(instr, root))
        {
            _x = root["datax"].asInt();
            _y = root["datay"].asInt();
            _oper = root["oper"].asInt();
        }
        else
        {
            std::cout << "bug!!" << std::endl;
        }
    }
    void Print()
    {
        std::cout << "_x: " << _x << std::endl;
        std::cout << "_y: " << _y << std::endl;
        std::cout << "oper: " << _oper << std::endl;
    }
    ~Request()
    {
    }

private:
    int _x;
    int _y;
    char _oper;
};
//应答报文
class Response
{
public:
    Response() : _result(0), _exitcode(0) {}
    void Serialize(std::string *outstr)//序列化
    {
        Json::Value root;
        root["result"] = _result;
        root["exitcode"] = _exitcode;
        Json::FastWriter write;
        *outstr = write.write(root);
    }
    void Deserialize(std::string &instr)
    {
        Json::Value root;
        Json::Reader reader;
        if (reader.parse(instr, root))
        {
            _result = root["result"].asInt();
            _exitcode = root["exitcode"].asInt();
        }
        else
        {
            std::cout << "bug!!!!!" << std::endl;
        }
    }
    ~Response() {}

private:
    int _result;
    int _exitcode;
};
//////////////////////////////////////////
const std::string gsep = "\r\n";
using callback_t = std::function<Response(const Request &)>;
class Protocol
{
public:
    Protocol() {}
    Protocol(callback_t cb) : _cb(cb)
    {
    }
    ~Protocol() {}
private:
    std::string Package(const std::string &jsonstr)
    {
        uint32_t len = jsonstr.size();
        return std::to_string(len) + gsep + jsonstr + gsep;
    }
    int Uppackage( std::string &streamstr, std::string *jsonstr)//提取报文
    {
        auto pos = streamstr.find(gsep);
        if (pos == std::string::npos)
            return 0;
        std::string packlenstr = streamstr.substr(0, pos);
        for (auto &c : packlenstr)
        {
            if (c < '0' || c > '9')
            {
                return -1;
            }
        }
        uint32_t packlenint = std::stoi(packlenstr);
        uint32_t targetlen = packlenint+packlenstr.size()+2*gsep.size();
        if(streamstr.size()<targetlen)
        {
            return 0;
        }
        *jsonstr= streamstr.substr(pos+gsep.size(),packlenint);
        streamstr.erase(0,targetlen);
        return targetlen;
    }
public:
    std::string HandlerRequest(std::string &streamstr)
    {
        LOG(LogLevel::DEBUG)<<"Enther HandlerRequest";
        std::string resp_package;
        while(true)
        {
            std::string jsonstring;
            int n =Uppackage(streamstr,&jsonstring);//提取
            if(n==-1)
            {
                LOG(LogLevel::ERROR)<<"uppackage error";
                exit(1);
            }
            else if(n==0)
            {
                LOG(LogLevel::DEBUG)<<"解析完毕";
            }
            //反序列化
            std::unique_ptr<Request> _request =std::make_unique<Request>();
            _request->Deserialise(jsonstring);
            _request->Print();
            //处理交给业务层
            Response _response =_cb(*_request);
            //序列化
            std::string respjsonstr;
           _response.Serialize(&respjsonstr);
            //封包
            resp_package += Package(respjsonstr);
          
        }
        return resp_package;
    }

private:
    callback_t _cb;
};
#endif 
这里我创建的是一个如:35\r\n{"datax":10,"datay":20,"oper":43}\r\n这样的协议以\r\n为分割符 格式为“正文长度\r\n正文\r\n” 协议层得要有可以提取报文的功能并且可对报文进行序列化和反序列化 HandlerRequest函数用来处理报文并交给业务层处理 分为从字节流提取报文,提取到完整的报文对报文进行分割处理提取正文 并反序列化交给业务层,业务层后返回一个序列化正文,对处理完的正文进行打包返回到网络层;
posted on 2026-10-15 16:20  zh2422  阅读(2)  评论(0)    收藏  举报