当前位置: 首页 > news >正文

网站建设 流程 域名申请猪八戒网接单平台

网站建设 流程 域名申请,猪八戒网接单平台,陕西省人民政府网官网首页,wordpress+商场源码🥁作者: 华丞臧. 📕​​​​专栏:【网络】 各位读者老爷如果觉得博主写的不错,请诸位多多支持(点赞收藏关注)。如果有错误的地方,欢迎在评论区指出。 推荐一款刷题网站 👉 LeetCode刷题网站 文章…

🥁作者华丞臧.
📕​​​​专栏:【网络】
各位读者老爷如果觉得博主写的不错,请诸位多多支持(点赞+收藏+关注)。如果有错误的地方,欢迎在评论区指出。
推荐一款刷题网站 👉 LeetCode刷题网站


文章目录

  • 一、应用层
  • 二、网络版本计算器
    • 2.1 协议定制
    • 2.2 协议实现
      • encode
      • decode
      • 定制请求 -- Requset
      • 定制响应 -- Response
      • 输入参数读取
      • 测试
    • 2.3 使用第三方库
      • 测试


一、应用层

  • 程序员写的一个个解决实际问题满足日常需求的网络程序都是在应用层的。
  • 协议是一种“约定”,socket api的接口在读写数据时,都是按“字符串”的方式来发送接收的。
  • 如果我们要传输一些“结构化数据”,能直接传输吗?肯定是不能直接传输的,结构化数据存在一些问题,比如C语言中结构体需要结构体对齐,C++中类同样需要对齐,会浪费网络资源,并且不同操作系统的大小端在不同编译器下可能不同。

所以对于需要传输结构化数据,我们可以进行约定:

  • 定义结构体来表示我们需要交互的信息;
  • 发送数据时将这个结构体按照约定的规则转换成字符串,接收到数据的时候再按照相同的规则把字符串转回结构体。
  • 序列化:将结构体数据转换成字符串的过程。
  • 反序列化:将字符串数据转换回结构化数据的过程。

二、网络版本计算器

在进行结构化数据的网络通信时,需要将数据序列化成字符串再发送给对方,但是对方并不知道传输数据的长度,也不知道如何从字符串的数据中读取结构化的数据;因此在进行网络通信之间,通信的双发需要进行约定,比如:约定如何确定序列化数据的长度以及用什么格式来反序列化字符串。
在这里我们先手写一个定制协议,约定如下:

  • 计算器格式通常是:1+2、 2*3、9/3;
  • 序列化字符串首部几个字节表示长度;
  • 有效载荷通过空格隔开;
  • 表示长度的报头和有效载荷通过\r\n隔开;
  • 报文之间也是用\r\n隔开

2.1 协议定制

在这里插入图片描述
客户端和服务端代码请看👉序列化和反序列化

#pragma once
#include <iostream>
#include <string>
#include <assert.h>#include "Log.hpp"#define CRLF "\r\n"
#define CRLF_LEN strlen(CRLF)
#define SPACE " "
#define SPACE_LEN strlen(SPACE)
#define OPS "+-*/%"// encode,对整个序列化之后的字符串进行添加长度
//"strlen\r\nXXXXXX\r\n"
std::string encode(std::string &in, uint32_t len)
{}// decode,整个序列化之后的字符串进行提取长度
// 1. 必须具有完整的长度
// 2. 必须具有和len相符合的有效载荷
// 我们才返回有效载荷和len
// 否则,我们就是一个检测函数!
// 9\r\n100 + 200\r\n    9\r\n112 / 200\r\n
std::string decode(std::string &in, uint32_t *len)
{}// 定制请求 
class Request
{
public:Request(){}~Request(){}int& getX(){ return x_;}int& getY(){ return y_;}char& getOp(){ return op_;}// 序列化void serialization(std::string *out){}// 反序列化bool deserialization(std::string &in){}void debug(){}
private:// 需要计算的数据int x_; int y_;// 需要计算的种类,"+ - * / %"char op_;
};// 定制响应
class Response
{
public:Response():result_(0),exitCode_(0){}~Response(){}// 序列化void serialization(std::string *out){}// 反序列化bool deserialization(std::string &in){}
public:// 退出状态,0标识运算结果合法,非0标识运算结果是非法的int exitCode_; // 运算结果int result_;
};bool makeReuquest(const std::string &str, Request *req)
{}

2.2 协议实现

encode

按照约定需要在序列化之后的字符串首部加上有效载荷的长度并用\r\n隔开,并且结尾也需要加上\r\n
在这里插入图片描述

// encode,对整个序列化之后的字符串进行添加长度
//"strlen\r\nXXXXXX\r\n"
std::string encode(std::string &in, uint32_t len)
{// "exitCode_ result_"// "len\r\n" "exitCode_ result_\r\n"std::string encodeStr = std::to_string(len);encodeStr += CRLF;encodeStr += in;encodeStr += CRLF;//std::cout << "debug->encode-> " << encodeStr << std::endl;return encodeStr;
}

decode

  • 第一步要先提取有效载荷的长度,再根据长度检查字符串中是否含有一个完整的有效载荷;
  • 如果具有完整的有效载荷,可以通过长度来提取有效载荷。
  • 注意如果需要进行多次提取,需要将读取出的字符串删除。
// decode,整个序列化之后的字符串进行提取长度
// 1. 必须具有完整的长度
// 2. 必须具有和len相符合的有效载荷
// 我们才返回有效载荷和len
// 否则,我们就是一个检测函数!
// 9\r\n100 + 200\r\n    9\r\n112 / 200\r\n
std::string decode(std::string &in, uint32_t *len)
{assert(len);// 1. 确认是否是一个包含len的有效字符串*len = 0;size_t pos = in.find(CRLF);if(pos == std::string::npos)return "";// 2. 提取长度std::string strLen = in.substr(0, pos);int intLen = atoi(strLen.c_str());// 3. 确认有效载荷也是符合要求的int surplus = in.size() - 2 * CRLF_LEN - pos;if(surplus < intLen){return "";}// 4. 确认有完整的报文结构std::string package = in.substr(pos + CRLF_LEN, intLen);*len = intLen;// 5. 将当前报文完整的从in中全部移除掉int remLen = strLen.size() + 2 *CRLF_LEN + package.size();in.erase(0, remLen);// 6. 正常返回return package;
}

定制请求 – Requset

定制请求,就是给请求方一个存放结构化数据的空间,请求方可以通过定制好的协议进行序列化得到字符串,然后就可以与服务端进行网络通信了;Request中的反序列化通常是给服务端提取请求方的结构化数据,所以服务端可以根据结构化数据向请求方进行响应。

序列化:

  • 序列化出的数据属于有效载荷,因此按照协议需要使用空格隔开;

反序列化:

  • 按照协议规定,结构化的数据在字符串中是通过空格隔开的,所以我们可以根据字符串中的两个空格将数据结构化提取出来。
#define CRLF "\r\n"
#define CRLF_LEN strlen(CRLF)
#define SPACE " "
#define SPACE_LEN strlen(SPACE)// 定制请求 
class Request
{
public:Request(){}~Request(){}int& getX(){ return x_;}int& getY(){ return y_;}char& getOp(){ return op_;}// 序列化void serialization(std::string *out){// 100 + 200 // "100 + 200"std::string dateOne = std::to_string(x_);std::string dateTwo = std::to_string(y_);std::string dateOp = std::to_string(op_);*out = dateOne;*out += SPACE;*out += op_;*out += SPACE;*out += dateTwo;//std::cout << *out << std::endl;}// 反序列化bool deserialization(std::string &in){//std::cout << 0 << std::endl;// 100 + 200 size_t spaceOne = in.find(SPACE);if(spaceOne == std::string::npos) return false;//std::cout << 1 << std::endl;size_t spaceTwo = in.rfind(SPACE);if(spaceTwo == std::string::npos) return false;//std::cout << 2 << std::endl;std::string dateOne = in.substr(0, spaceOne);std::string dateTwo = in.substr(spaceTwo + SPACE_LEN);std::string dateOp = in.substr(spaceOne + SPACE_LEN, spaceTwo - (spaceOne + SPACE_LEN));if(dateOp.size() != 1) {printf("%d:%c\n", dateOp.size(), dateOp.c_str());return false;}//std::cout << 3 << std::endl;// 转成内部成员x_ = atoi(dateOne.c_str());y_ = atoi(dateTwo.c_str());op_ = atoi(dateOp.c_str());return true;}void debug(){std::cout << "x_" << x_ << std::endl;std::cout << "y_" << y_ << std::endl;std::cout << "op_" << op_ << std::endl;}
private:// 需要计算的数据int x_; int y_;// 需要计算的种类,"+ - * / %"char op_;
};

定制响应 – Response

响应是服务端在对客户端的请求提供服务之后给客户端返回的结果,所以Response需要能够存放服务结果以及发生错误时的状态码;而结果和错误码是数据化结构,所以需要序列化之后在传输给客户端,客户端在拿到响应后需要进行反序列化拿到结果和状态码。序列胡和反序列化过程与定制请求类似。

#define CRLF "\r\n"
#define CRLF_LEN strlen(CRLF)
#define SPACE " "
#define SPACE_LEN strlen(SPACE)
// 定制响应
class Response
{
public:Response():result_(0),exitCode_(0){}~Response(){}// 序列化void serialization(std::string *out){// "exitCode_ result_"std::string ec = std::to_string(exitCode_);std::string res = std::to_string(result_);*out = ec;*out += SPACE;*out += res;}// 反序列化bool deserialization(std::string &in){// "nextiCode_ result_"size_t pos = in.find(SPACE);if(pos == std::string::npos) return false;std::string ec = in.substr(0, pos);std::string res = in.substr(pos + SPACE_LEN);exitCode_ = atoi(ec.c_str());result_ = atoi(res.c_str());return true;}public:// 退出状态,0标识运算结果合法,非0标识运算结果是非法的int exitCode_; // 运算结果int result_;
};

输入参数读取

我们在客户端输入时是按照字符串的格式输入的,所以为了能够使用定制协议,需要进行反序列化即将输入的字符串数据按照协议中的结构化数据提取出来。

#define OPS "+-*/%"bool makeReuquest(const std::string &str, Request *req)
{// 123+1  1*1 1/1char strtmp[1024];snprintf(strtmp, sizeof strtmp, "%s", str.c_str());char *left = strtok(strtmp, OPS);if (!left)return false;char *right = strtok(nullptr, OPS);if (!right)return false;char mid = str[strlen(left)];req->getX() = atoi(left);req->getY() = atoi(right);req->getOp() = mid;return true;
}

测试

  • IP:127.0.0.1 --》测试
    在这里插入图片描述
  • IP:119.91.213.117 --》测试
    在这里插入图片描述

2.3 使用第三方库

大佬也写了第三方库来支持序列化和反序列化,在这里我使用的jsoncpp,安装方式如下:

sudo yum install -y jsoncpp-devel

第三方库的使用较之我们自己实现无疑方便了很多,不用自己造轮子。

#pragma once
#include <iostream>
#include <string>
#include <assert.h>
#include <jsoncpp/json/json.h>#include "Log.hpp"#define CRLF "\r\n"
#define CRLF_LEN strlen(CRLF)
#define SPACE " "
#define SPACE_LEN strlen(SPACE)
#define OPS "+-*/%"// 定制请求 
class Request
{
public:Request(){}~Request(){}int& getX(){ return x_;}int& getY(){ return y_;}char& getOp(){ return op_;}// 序列化void serialization(std::string *out){//json// 1. Value对象,万能对象// 2. json是基于KV// 3. json有两套操作方法// 4. 序列化的时候,会将所有的数据内容,转换成为字符串Json::Value root;  //,万能对象,任意类型root["x"] = x_;root["y"] = y_;root["op"] = op_;Json::FastWriter fw;  //Json::StyledWriter fw;*out = fw.write(root); //序列化}// 反序列化bool deserialization(std::string &in){Json::Value root;Json::Reader rd;rd.parse(in, root);x_ = root["x"].asInt();y_ = root["y"].asInt();op_ = root["op"].asInt();return true;}void debug(){std::cout << "x_" << x_ << std::endl;std::cout << "y_" << y_ << std::endl;std::cout << "op_" << op_ << std::endl;}
private:// 需要计算的数据int x_; int y_;// 需要计算的种类,"+ - * / %"char op_;
};// 定制响应
class Response
{
public:Response():result_(0),exitCode_(0){}~Response(){}// 序列化void serialization(std::string *out){Json::Value root;root["exitCode"] = exitCode_;root["result"] = result_;Json::FastWriter fw;*out = fw.write(root); //序列化}// 反序列化bool deserialization(std::string &in){Json::Value root;Json::Reader rd;rd.parse(in, root);exitCode_ = root["exitCode"].asInt();result_ = root["result"].asInt();return true;}public:// 退出状态,0标识运算结果合法,非0标识运算结果是非法的int exitCode_; // 运算结果int result_;
};

测试

  • 使用Json::FastWriter fw;
    在这里插入图片描述
  • 使用Json::StyledWriter fw;
    在这里插入图片描述
http://www.shuangfujiaoyu.com/news/26888.html

相关文章:

  • 建立网站有什么用网络优化器
  • 关于网站建设的期刊文献济南百度推广代理商
  • 查网站跳出率网站服务器查询
  • 网站策划机构产品软文案例
  • 个人商城网站怎么做百度咨询
  • 宁波网站制作工作室北京优化seo排名优化
  • 民非企业网站建设费怎么记账网络营销总结
  • 大型新型网站程序员培训机构排名
  • 南宁电子推广网站seo是搜索引擎优化吗
  • wordpress英文站源码做网站需要多少钱 都包括什么
  • 做淘宝详情页好的网站360建站官网
  • 代做ppt的网站产品推广公司
  • 为企业提供网站建设服务抖音seo系统
  • wordpress 数据站seo最新
  • 政府信息网站如何建设百度一下首页网址
  • 南沙滩做网站公司关键词挖掘站长工具
  • 雄县哪做网站关键词排名怎么做上首页
  • 动态网站上的查询怎么做seo研究中心好客站
  • 怎么选择扬中网站建设必应bing国内版
  • 网站维护的方式有哪几种seo免费诊断电话
  • 柳州制作网站南京seo排名
  • 做网站 图片更好看郑州seo排名第一
  • wordpress去除顶部导航seo和sem的关系
  • 企业门户网站系统苏州seo公司
  • 运城手机网站制作武汉网站seo服务
  • 汉口做网站百度识图在线识图
  • 株洲网站建设怎么建立一个属于自己的网站
  • 数码网站建设今日资讯最新消息
  • 怎么早网站上放广告网络营销毕业论文范文
  • 云服务器建设网站用什么系统org域名注册