玉石电商网站建设方案推广网站制作
目录
1.序列化和反序列化的协议实现
(1)基类实现
(2)子类实现
2.计算功能实现
3.TCPServer调用
4.对会话和表示层的理解
5.网络计算器相关代码
(1)myProtocol.hpp
(2)TcpServerMain.cc
(3)myProtocol.hpp
本文在前面TCPServer、线程池、日志已经实现的情况下,以网络计算器的实现为主线,重点理解OSI定义的七层模型,以及理解为什么后面精简到了五层。
1.序列化和反序列化的协议实现
客户端发消息前要对即将发出的字符串进行序列化,服务端收到字符串后要对字符串进行反序列化。之后执行完结果后同样需要序列化和反序列化的过程。除此之外,和之前的TCP服务没有区别了。
(1)基类实现
我们将公共部分提取出来,就是手动对json后的内容再次进行包装和解包的过程。
(2)子类实现
注意接收和回应的参数和返回值分别代表的含义即可,其余的都是字符串操作。
2.计算功能实现
接收结构化数据,返回结构化数据
3.TCPServer调用
利用前面实现好的类进行调用即可
4.对会话和表示层的理解
我们发现在代码中表示层和会话层都被嵌入进去了,而非冗余部分。表示层和会话层属于协议栈上层了,越往上,需求不一样,越难统一,因此表示层和会话层无法写到内核里,需要根据需求手动实现,并且表示层和会话层大多都有了相应的现成方案,大多数人只需要关注应用层即可。
因此,TCP/IP协议将上三层压成了一层,总体归为应用层,但事实上这三层永不可缺。
5.网络计算器相关代码
(1)myProtocol.hpp
#pragma once#include <iostream>
#include <string>
#include <sstream>
#include <fstream>#include <jsoncpp/json/json.h> //json方案需要包含的头文件using namespace std;// 结构化数据
class DataInfo
{
public:DataInfo(int _x = 0, char _oper = 0, int _y = 0, int _result = 0, int _error = 0): _x(_x), _oper(_oper), _y(_y), _result(_result), _error(_error){}int _x;char _oper;int _y;int _result;int _error;
};class myProtocol
{
protected:// myProtocol协议的一部分,专门用于信息的编码和解码string Encode(const string &message) // 专门负责encode{string encodedMessage = to_string(message.length()) + "\r\n" + message + "\r\n"; // 有效载荷长度+换行符+有效载荷+换行符return encodedMessage;}string Decode(const string &encodedMessage) // 专门负责decode{size_t first_pos = encodedMessage.find("\r\n"); // 查找第一个换行符if (first_pos == string::npos)return ""; // 如果没有找到第一个换行符,则返回空字符串int len = stoi(encodedMessage.substr(0, first_pos)); // 有效载荷长度if (encodedMessage.length() < first_pos + len + 4) // 如果有效载荷长度大于编码消息长度,则返回空字符串return "";return encodedMessage.substr(first_pos + 2, len); // 有效载荷}public:virtual string Serialize(DataInfo &info) = 0; // 序列化,同时进行编码virtual DataInfo Deserialize(const string &encodedMessage) = 0; // 反序列化,同时进行解码virtual ~myProtocol() = default;
};class Request : public myProtocol
{
public:string Serialize(DataInfo &info) // 序列化,同时进行编码{Json::Value root;root["x"] = info._x;root["oper"] = info._oper;root["y"] = info._y;root["result"] = info._result; // 结果和错误码root["error"] = info._error;Json::StreamWriterBuilder writer;std::string json_string = Json::writeString(writer, root);return Encode(json_string); // 对json后的数据编码}DataInfo Deserialize(const string &encodedMessage) // 反序列化,同时进行解码{string str = Decode(encodedMessage); // 对json后的数据编码if (str.empty())return DataInfo(); // 反序列化失败,传入的数据不完整Json::Value root;Json::Reader reader;bool parsingSuccessful = reader.parse(str, root);if (!parsingSuccessful)return DataInfo();DataInfo info;info._x = root["x"].asInt();info._y = root["y"].asInt();info._oper = root["oper"].asInt();info._result = root["result"].asInt();info._error = root["error"].asInt();return info;}
};class Response : public myProtocol
{
public:string Serialize(DataInfo &info) // 序列化,同时进行编码{Json::Value root;root["x"] = info._x;root["oper"] = info._oper;root["y"] = info._y;root["result"] = info._result; // 结果和错误码root["error"] = info._error;Json::StreamWriterBuilder writer;std::string json_string = Json::writeString(writer, root);return Encode(json_string); // 对json后的数据编码}DataInfo Deserialize(const string &encodedMessage) // 反序列化,同时进行解码{string str = Decode(encodedMessage); // 对json后的数据编码if (str.empty())return DataInfo(); // 反序列化失败,传入的数据不完整Json::Value root;Json::Reader reader;bool parsingSuccessful = reader.parse(str, root);if (!parsingSuccessful)return DataInfo();DataInfo info;info._x = root["x"].asInt();info._y = root["y"].asInt();info._oper = root["oper"].asInt();info._result = root["result"].asInt();info._error = root["error"].asInt();return info;}
};
(2)TcpServerMain.cc
#include "TcpServer.hpp"int main()
{FILE_LOG(); // 打开日志文件,日志输出而非打印到屏幕,守护进程模式myDaemon(false, false);myCalculator calculator; // 创建一个计算器对象unique_ptr<TcpServer> server(make_unique<TcpServer>()); // 创建一个服务端对象server->start(); // 启动服务端return 0;
}
(3)myProtocol.hpp
#pragma once#include <iostream>
#include <string>
#include <sstream>
#include <fstream>#include <jsoncpp/json/json.h> //json方案需要包含的头文件using namespace std;// 结构化数据
class DataInfo
{
public:DataInfo(int _x = 0, char _oper = 0, int _y = 0, int _result = 0, int _error = 0): _x(_x), _oper(_oper), _y(_y), _result(_result), _error(_error){}int _x;char _oper;int _y;int _result;int _error;
};class myProtocol
{
protected:// myProtocol协议的一部分,专门用于信息的编码和解码string Encode(const string &message) // 专门负责encode{string encodedMessage = to_string(message.length()) + "\r\n" + message + "\r\n"; // 有效载荷长度+换行符+有效载荷+换行符return encodedMessage;}string Decode(const string &encodedMessage) // 专门负责decode{size_t first_pos = encodedMessage.find("\r\n"); // 查找第一个换行符if (first_pos == string::npos)return ""; // 如果没有找到第一个换行符,则返回空字符串int len = stoi(encodedMessage.substr(0, first_pos)); // 有效载荷长度if (encodedMessage.length() < first_pos + len + 4) // 如果有效载荷长度大于编码消息长度,则返回空字符串return "";return encodedMessage.substr(first_pos + 2, len); // 有效载荷}public:virtual string Serialize(DataInfo &info) = 0; // 序列化,同时进行编码virtual DataInfo Deserialize(const string &encodedMessage) = 0; // 反序列化,同时进行解码virtual ~myProtocol() = default;
};class Request : public myProtocol
{
public:string Serialize(DataInfo &info) // 序列化,同时进行编码{Json::Value root;root["x"] = info._x;root["oper"] = info._oper;root["y"] = info._y;root["result"] = info._result; // 结果和错误码root["error"] = info._error;Json::StreamWriterBuilder writer;std::string json_string = Json::writeString(writer, root);return Encode(json_string); // 对json后的数据编码}DataInfo Deserialize(const string &encodedMessage) // 反序列化,同时进行解码{string str = Decode(encodedMessage); // 对json后的数据编码if (str.empty())return DataInfo(); // 反序列化失败,传入的数据不完整Json::Value root;Json::Reader reader;bool parsingSuccessful = reader.parse(str, root);if (!parsingSuccessful)return DataInfo();DataInfo info;info._x = root["x"].asInt();info._y = root["y"].asInt();info._oper = root["oper"].asInt();info._result = root["result"].asInt();info._error = root["error"].asInt();return info;}
};class Response : public myProtocol
{
public:string Serialize(DataInfo &info) // 序列化,同时进行编码{Json::Value root;root["x"] = info._x;root["oper"] = info._oper;root["y"] = info._y;root["result"] = info._result; // 结果和错误码root["error"] = info._error;Json::StreamWriterBuilder writer;std::string json_string = Json::writeString(writer, root);return Encode(json_string); // 对json后的数据编码}DataInfo Deserialize(const string &encodedMessage) // 反序列化,同时进行解码{string str = Decode(encodedMessage); // 对json后的数据编码if (str.empty())return DataInfo(); // 反序列化失败,传入的数据不完整Json::Value root;Json::Reader reader;bool parsingSuccessful = reader.parse(str, root);if (!parsingSuccessful)return DataInfo();DataInfo info;info._x = root["x"].asInt();info._y = root["y"].asInt();info._oper = root["oper"].asInt();info._result = root["result"].asInt();info._error = root["error"].asInt();return info;}
};