文章目录
1. 协议
- 注意:我们程序员写的一个个解决我们实际问题, 满足我们日常需求的网络程序, 都是在应用层。
- 协议是一种 “约定”
socket api的接口, 在读写数据时, 都是按 “字符串” 的方式来发送接收的. 如果我们要传输一些"结构化的数据" 怎么做呢?
- 发送数据时将这个结构体按照一个规则转换成字符串, 接收到数据的时候再按照相同的规则把字符串转化回结构体。
2. 网络版计算器简易实现代码链接
- 完整代码我放到git仓库了哈~
- 链接:
https://gitee.com/ding-xushengyun/linux__cpp/tree/master/NetCal
3. 网络版计算器
2-1. 约定的协议方案有两种
约定方案一:
- 客户端发送一个形如"1+1"的字符串;
- 这个字符串中有两个操作数, 都是整形;
- 两个数字之间会有一个字符是运算符, 运算符只能是 +
- 数字和运算符之间没有空格。
约定方案二(我们的代码实现采用方案二):
- 定义结构体来表示我们需要交互的信息;
- 发送数据时将这个结构体按照一个规则转换成字符串, 接收到数据的时候再按照相同的规则把字符串转化回结构体;
- 这个过程叫做 “序列化” 和 “反序列化”
注意:无论我们采用方案一, 还是方案二, 还是其他的方案, 只要保证, 一端发送时构造的数据, 在另一端能够正确的进行解析, 就是ok的. 这种约定, 就是应用层协议。
- 当然我们自己简单实现的协议比较简陋(不能应用于任何场景);库里的json更强大。
2-3. 协议代码框架
结果和计算过程都有序列和反序列化
#pragma once
#include <iostream>
#include <string>
#include <cstring>
#include <sys/types.h>
#include <sys/socket.h>
#include <jsoncpp/json/json.h>
using std::cout;
using std::endl;
using std::string;
namespace ns_protocol
{
#define MYSELF 1
#define SPACE " "
#define SPACE_LINE strlen(SPACE)
#define SEP "\r\n"
#define SEP_LINE strlen(SEP)
class Request // 计算数据
{
public:
// "_x _op _y"
string Serialize() // 序列化
{
#ifdef MYSELF
// 自己模拟的协议
#else
// json
#endif
}
// "111 + 222"
bool Deserialized(const string &str) // 反序列化
{
#ifdef MYSELF
// 自己模拟的协议
#else
// json
return true;
#endif
}
Request() {
}
Request(int x, int y, int op) : _x(x), _y(y), _op(op)
{
}
public:
int _x;
int _y;
char _op; // '+' '-' '*' '/' '%'
};
class Response // 结果
{
public:
// _code _result
string Serialize() // 序列化
{
#ifdef MYSELF
// 自己模拟的协议
#else
// json
#endif
}