1 Star 0 Fork 0

遇健/Linux

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
Protocol.hpp 4.90 KB
一键复制 编辑 原始数据 按行查看 历史
遇健 提交于 2023-07-27 22:15 +08:00 . 自定协议实现序列化和反序列化
#include<string>
#include<iostream>
#include<vector>
#include<cstring>
#include<sys/types.h>
#include<sys/socket.h>
#include"Util.hpp"
using namespace std;
// 给网络版本计算器定制协议
namespace Protocol_ns
{
#define SEP " "
#define SEP_LEN strlen(SEP) // 绝对不能写成sizeof
#define HEADER_SEP "\r\n"
#define HEADER_SEP_LEN strlen("\r\n")
// "长度"\r\n" "_x op _y"\r\n
// "10 + 20" => "7"r\n""10 + 20"\r\n => 报头 + 有效载荷
// 请求/响应 = 报头\r\n有效载荷\r\n
// 请求 = 报头\r\n有效载荷\r\n报头\r\n有效载荷\r\n报头\r\n有效载荷\r\n
// "10 + 20" => "7"r\n""10 + 20"\r\n
string AddHeader(string&str)
{
cout<<"AddHeader 之前:\n"
<<str<<endl;
string s=to_string(str.size());
s+=HEADER_SEP;
s+=str;
s+=HEADER_SEP;
cout<<"AddHeader 之后:\n"
<<s<<endl;
return s;
}
// "7"r\n""10 + 20"\r\n => "10 + 20"
string RemoveHeader(const string&str,int len)
{
cout<<"RemoveHeader 之前:\n"
<<str<<endl;
// 从后面开始截取
string res=str.substr(str.size()-HEADER_SEP_LEN-len,len);
cout<<"RemoveHeader 之后:\n"
<<res<<endl;
return res;
}
int Readpackage(int sock,string&inbuffer,string*package)
{
cout<<"ReadPackage inbuffer 之前:\n"
<<inbuffer<<endl;
// 边读取
char buffer[1024];
ssize_t s=recv(sock,&buffer,sizeof(buffer)-1,0);
if(s<=0)
return -1;
buffer[s]=0;
inbuffer+=buffer;
cout<<"ReadPackage inbuffer 之中:\n"
<<inbuffer<<endl;
// 边分析, "7"r\n""10 + 20"\r\n
auto pos=inbuffer.find(HEADER_SEP);
if(pos==string::npos)
return 0;
string lenStr=inbuffer.substr(0,pos); // 获取头部字符串, 没有动inbuffer
int len=Util::toInt(lenStr); // 得到有效载荷的长度 => "123" -> 123
int targetPackageLen=len+2*HEADER_SEP_LEN+lenStr.size(); // 得到整个报文长度
if(inbuffer.size()<targetPackageLen) // 不是一个完整的报文
return 0;
*package=inbuffer.substr(0,targetPackageLen); // 提取到了报文有效载荷, 没有动inbuffer
inbuffer.erase(0,targetPackageLen); // 从inbuffer中直接移除整个报文
cout<<"ReadPackage inbuffer 之后:\n"
<<inbuffer<<endl;
return len;
}
// Request && Response都要提供序列化和反序列化功能
// 1. 自己手写
// 2. 用别人的
class Request
{
public:
Request()
{
}
Request(int x,int y,char op)
:_x(x)
,_y(y)
,_op(op)
{
}
// 序列化: struct->string
bool Serialize(string* outStr)
{
*outStr="";
string x_string=to_string(_x);
string y_string=to_string(_y);
// 手动序列化
*outStr=x_string + SEP + _op + SEP + y_string;
return true;
}
// 反序列化: string->struct
bool Deserialize(const string&inStr)
{
// inStr: 10 + 20 => [0]=>10, [1]=>+, [2]=>20
vector<string> result;
Util::StringSplit(inStr,SEP,&result);
if(result.size()!=3)
return false;
if(result[1].size()!=1)
return false;
_x=Util::toInt(result[0]);
_y=Util::toInt(result[2]);
_op=result[1][0];
}
~Request()
{
}
public:
// _x op _y ==> 10 * 9 ? ==> 10 / 0 ?
int _x;
int _y;
char _op;
};
class Response
{
public:
Response()
{
}
Response(int result,int code)
:_result(result)
,_code(code)
{
}
// 序列化: struct->string
bool Serialize(string* outStr)
{
// _result _code
*outStr="";
string res_string = to_string(_result);
string code_string = to_string(_code);
// 手动序列化
*outStr=res_string + SEP + code_string;
return true;
}
// 反序列化: string->struct
bool Deserialize(const string&inStr)
{
// 10 0
vector<string> result;
Util::StringSplit(inStr,SEP,&result);
if(result.size()!=2)
return false;
_result=Util::toInt(result[0]);
_code=Util::toInt(result[1]);
return true;
}
~Response()
{
}
public:
int _result;
int _code; // 0 success; 1,2,3,4代表不同错误码
};
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
C++
1
https://gitee.com/yu-jian-Rena/linux.git
git@gitee.com:yu-jian-Rena/linux.git
yu-jian-Rena
linux
Linux
master

搜索帮助