【计算机网络】协议定制

一、结构化数据传输流程

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

对于序列化和反序列化,有现成的解决方案:①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.整体调用逻辑

相关推荐
努力努力再努力wz1 分钟前
【分布式系统与 RPC 框架系列】从单机瓶颈到远程调用:一文理解分布式架构与 RPC 原理
linux·网络·c++·分布式·网络协议·rpc·架构
卷无止境2 分钟前
Python的魔术方法:那些藏在双下划线背后的魔法
后端·python
Ivanqhz10 分钟前
Rust parse() 浅析
开发语言·后端·rust
卷无止境15 分钟前
别再被"乱码"吓到了:Python文件操作的门道
后端·python
神仙别闹18 分钟前
基于C++实现(控制台)景区旅游管理系统
开发语言·c++·旅游
程序员爱钓鱼19 分钟前
Rust Result 详解:可靠的错误处理机制
前端·后端·rust
程序员爱钓鱼27 分钟前
GOPATH 与 Go Modules:Go 项目依赖管理的演变
后端·go
GIS数据转换器29 分钟前
智慧灌区管理平台
大数据·服务器·网络·数据库·人工智能·生活
寒水馨2 小时前
Linux下载、安装 Codex CLI(附安装包codex-x86_64-unknown-linux-musl.tar.gz)
linux·openai·终端·ai编程·codex·智能体·codex cli
其实防守也摸鱼2 小时前
KMP全栈开发:从Android到AI Agent的技术演进与实践
android·运维·网络·人工智能·学习·安全·macos