【计算机网络】协议定制

一、结构化数据传输流程

这里涉及协议定制序列化/反序列化的知识

对于序列化和反序列化,有现成的解决方案:①json ②probuff ③xml

二、理解发送接收函数

我们调用的所有发送/接收函数,根本就不是把数据发送到网络中!本质都是拷贝函数!

Client -> Server:tcp发送的本质,就是将数据从c的发送缓冲区,拷贝到s的接收缓冲区!

Client -> Server:tcp发送的本质,就是将数据从c的发送缓冲区,拷贝到s的接收缓冲区!

每一端都有一套发送缓冲区/接收缓冲区 -> tcp是全双工的!

三、网络计算器流程

分析网络计算器的流程,就可以理解协议定制序列化/反序列化协议报头的作用了

说明:这里只谈论整体框架,不会细说每个函数的实现,想要完整代码的可以参考下面链接!

https://gitee.com/peter-chen-cs/linux_learning_code.git

1.定制协议

cpp 复制代码
#pragma once

#include <iostream>
#include <string>
#include <cstring>
#include <sys/types.h>
#include <sys/socket.h>
#include <jsoncpp/json/json.h>

// 添加报头
std::string enLength(const std::string &text)
// 去掉报头
bool deLength(const std::string &package, std::string *text)

// 请求
class Request
{
public:
    // 构造函数
    Request()
    // 序列化
    bool serialize(std::string *out)
    // 反序列化
    bool deserialize(const std::string &in)

public:
    int _x;
    int _y;
    char _op; // "_x _op _y"
};

// 响应
class Response
{
public:
    // 构造函数
    Response()
    // 序列化
    bool serialize(std::string *out)
    // 反序列化
    bool deserialize(const std::string &in)

public:
    int _exitcode; // 0表示计算成功;!0表示计算失败
    int _result;   // 计算结果
};

// 功能:保证读到的数据是一个完整的报文
bool recvPackage(int sock, std::string &inbuffer, std::string *text)

2.服务端

(1)calServer.hpp

cpp 复制代码
// 计算服务器-用于计算
class CalServer
{
public:
    // 构造函数
    CalServer()
    // 析构函数
    ~CalServer(){}
    // 初始化计算服务器
    void initServer()
    // 启动计算服务器
    void start(func_t func)
    {...handlerEntery(){func_t func()}...}

private:
    int _listensock;
    uint16_t _port;
};

typedef std::function<bool(const Request &req, Response &resp)> func_t; // 处理业务 

// 放在这里是为了保证解耦
void handlerEntery(int sock, func_t func)
{
    while (true)
    {
        // 1.从应用层缓冲区读取一个完整报文
        // 2.对请求Request反序列化-得到一个结构化的请求对象
        // 3.计算处理 -- 逻辑业务:得到一个结构化响应
        func(req, resp);
        // 4.对响应Response进行序列化-得到一个"字符串"
        // 5.添加包头,发送响应
    }
}

(2)calServer.cpp

cpp 复制代码
#include "calServer.hpp"
#include <memory>

bool cal(const Request &req, Response &resp)
{
    // 请求已经是结构化数据了,可以直接使用
    // 根据结构化请求完成计算
    // 构建结构化的响应
}


int main(int argc, char *argv[])
{
    // 启动服务器
    unique_ptr<CalServer> tsvr(new CalServer(port));
    tsvr->initServer();
    tsvr->start(cal);
    return 0;
}

3.客户端

(1)calClient.hpp

cpp 复制代码
class CalClient
{
public:
    // 构造函数
    CalClient(const std::string &serverip, const uint16_t &serverport)
    // 析构函数
    ~CalClient(){}
    // 初始化客户端
    void initClient()
    // 启动服务端
    void start()
    {
        // 建立连接
        while (true)
        {
            // 输入算式,并将输入的字符串转化成Request-ParseLine()
            // 将Request序列化
            // 添加报头
            // 发送到服务器

            // --服务器处理完发回来了--

            // 读取一个完整的响应
            // 去掉报头
            // 反序列化得到Response
        }
    }

    // 把从键盘输入的算式转化成一个Request请求
    Request ParseLine(const std::string &line)

private:
    int _sock;
    std::string _serverip;
    uint16_t _serverport;
};

(2)calClient.cpp

cpp 复制代码
#include "calClient.hpp"
#include <memory>

int main(int argc, char *argv[])
{
    // 启动客户端
}

4.整体调用逻辑

相关推荐
无泪无花月隐星沉3 分钟前
uos server 1070e lvm格式磁盘扩容分区
linux·运维·uos
Bruce_Liuxiaowei35 分钟前
Nmap+Fofa 一体化信息搜集工具打造
运维·开发语言·网络·网络安全
智航GIS37 分钟前
5.1 if语句基础
开发语言·python
食咗未37 分钟前
Linux USB HOST EXTERNAL STORAGE
linux·驱动开发
食咗未37 分钟前
Linux USB HOST HID
linux·驱动开发·人机交互
Xの哲學38 分钟前
Linux SLAB分配器深度解剖
linux·服务器·网络·算法·边缘计算
oioihoii39 分钟前
跨越进程的对话之从管道到gRPC的通信技术演进
c++
bu_shuo41 分钟前
MATLAB中的转置操作及其必要性
开发语言·算法·matlab
爱装代码的小瓶子1 小时前
算法【c++】二叉树搜索树转换成排序双向链表
c++·算法·链表
码界奇点1 小时前
基于Spring Boot的内容管理系统框架设计与实现
java·spring boot·后端·车载系统·毕业设计·源代码管理