网络(三)——协议是什么???

文章目录

  • 协议的概念
  • 结构化数据
  • 网络计算机
    • 服务端
    • 定制协议
    • 客户端代码

协议的概念

计算机之间的传输媒介是光信号和电信号。通过 “频率” 和 “强弱” 来表示 0 和 1 这样的信息。要想传递各种不同的信息,就需要约定好双方的数据格式。

结构化数据

我们知道TCP是面向字节流的方式进行通信,但如何保证读到一个完整的数据呢?
在使用QQ发送消息的时候别人接收到的不仅仅只有消息,而是包含了头像信息,昵称,消息。这就叫做结构化的数据;
这些结构化的数据可以打包成一个报文,这个就是序列化。把这个报文解开的过程就是反序列化;

序列化和反序列化的目的
在这里插入图片描述

我们可以认为网络通信和业务处理处于不同的层级;
网络通信时底层看到的都是二进制序列的数据;
业务处理时看得到则是可被上层识别的数据;
业务处理和网络通信之间交互即需要序列化和反序列化;

网络计算机

服务端

  1. 创建套接字;
  2. 绑定端口号;
  3. 设置监听;
  4. 启动服务器;
#include <iostream>
#include <string>
#include <cstring>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include "protocol.hpp"
using namespace std;int main(int argc, char* argv[])
{if (argc != 2){cerr << "Usage: " << argv[0] << " port" << endl;exit(1);}int port = atoi(argv[1]);// 创建套接字int listen_sock = socket(AF_INET, SOCK_STREAM, 0);if (listen_sock < 0){cerr << "socket error!" << endl;exit(2);}// 绑定struct sockaddr_in local;memset(&local, 0, sizeof(local));local.sin_family = AF_INET;local.sin_port = htons(port);local.sin_addr.s_addr = htonl(INADDR_ANY);if (bind(listen_sock, (struct sockaddr*)&local, sizeof(local)) < 0){cerr << "bind error!" << endl;exit(3);}// 监听if (listen(listen_sock, 5) < 0){cerr << "listen error!" << endl;exit(4);}// 启动服务器struct sockaddr peer;memset(&peer, 0, sizeof(peer));while (true){socklen_t len = sizeof(peer);int sock = accept(listen_sock, (struct sockaddr*)&peer, &len);if (sock < 0){cerr << "accept error!" << endl;continue;}pthread_t tid = 0;int* p = new int(sock);pthread_create(&tid, nullptr, Routine, p);}return 0;
}

定制协议

要保证通信双方能够进行通信,就必须让双方遵守某种协议,也就是双方的约定;
请求结构体中需要包括两个操作数,以及操作符;
响应结构体中需要包括一个计算结果,以及一个状态字段,表示本次计算状态;

// 请求结构体
typedef struct request{int _x; // 左操作数int _y; // 右操作数char _op; // 操作符
}_request;// 响应结构体
typedef struct response{int _code; // 计算状态int _result; // 计算结果
}_response;

协议定制必须要被客户端和服务端同时看到

客户端代码

  1. 创建套接字;
  2. 链接服务器;
  3. 发起请求;(构建请求、接受服务端的响应);
#include <iostream>
#include <string>
#include <cstring>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include "protocol.hpp"using namespace std;int main(int argc, char* argv[])
{if (argc != 3){cerr << "Usage: " << argv[0] << " server_ip server_port" << endl;exit(1);}string server_ip = argv[1];int server_port = atoi(argv[2]);// 创建套接字int sock = socket(AF_INET, SOCK_STREAM, 0);if (sock < 0){cerr << "socket error!" << endl;exit(2);}// 连接服务器struct sockaddr_in peer;memset(&peer, 0, sizeof(peer));peer.sin_family = AF_INET;peer.sin_port = htons(server_port);peer.sin_addr.s_addr = inet_addr(server_ip.c_str());if (connect(sock, (struct sockaddr*)&peer, sizeof(peer)) < 0) {cerr << "connect failed!" << endl;exit(3);}// 发起请求while (true){// 构建请求_request rq;cout << "请输入左操作数: ";cin >> rq._x;cout << "请输入右操作数: ";cin >> rq._y;cout << "请输入需要进行的操作";cin >> rq._op;send(sock, &rq, sizeof(rq), 0);// 接收响应_response rp;recv(sock, &rp, sizeof(rp), 0);cout << "status: " << rp._code << endl;cout << rq._x << rq._op << rq._y << " = " << rp._result << endl;}return 0;
}
  • send
ssize_t send(int sockfd, const void *buf, size_t len, int flags);

参数:

  • sockfd:特定的文件描述符,表示将数据写入该文件描述符对应的套接字
  • buf:需要发送的数据
  • len:需要发送数据的字节个数
  • flags:发送的方式,一般设置为0,表示阻塞式发送

返回值:

  • 写入成功返回实际写入的字节数,写入失败返回-1,同时错误码会被设置
  • recv
ssize_t recv(int sockfd, void *buf, size_t len, int flags);

参数:

  • sockfd:特定的文件描述符,表示从该文件描述符中读取数据
  • buf:数据的存储位置,表示将读取到的数据存储到该位置
  • len:数据的个数,表示从该文件描述符中读取数据的字节数
  • flags:读取的方式,一般设置为0,表示阻塞式读取

返回值:

  • 大于0,则表示本次实际读取到的字节个数
  • 等于0,则表示对端已经把连接关闭了
  • 小于0,则表示读取时遇到了错误

pthread_create中的Routine函数

void* Routine(void* arg)
{pthread_detach(pthread_self()); // 分离线程int sock = *(int*)arg;delete (int*)arg;while (true){_request rq;ssize_t size = recv(sock, &rq, sizeof(rq), 0);if (size > 0){_response rp = { 0, 0 };switch (rq.op){case '+':rp._result = rq._x + rq._y;break;case '-':rp._result = rq._x - rq._y;break;case '*':rp._result = rq._x * rq._y;break;case '/':if (rq._y == 0){rp.code = 1; // 除0错误}else{rp._result = rq._x / rq._y;}break;case '%':if (rq._y == 0){rp._code = 2; // 模0错误}else{rp._result = rq._x % rq._y;}break;default:rp._code = 3; // 非法运算break;}send(sock, &rp, sizeof(rp), 0);}else if (size == 0){cout << "service done" << endl;break;}else{cerr << "read error" << endl;break;}}close(sock);return nullptr;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/425194.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

pgrouting实战应用

1&#xff09;下载地区地区数据&#xff08;下载数据是XYZM 四位数据&#xff09; 2&#xff09;下载裁剪行政区数据 3&#xff09;使用arcgis pro添加路网数据和行政区数据 4&#xff09;裁剪数据&#xff0c;仅历下行政区路网 5&#xff09;arcgis pro要素转线&#xff0…

TalkSphere项目介绍

TalkSphere项目介绍 文章目录 TalkSphere项目介绍一、前言二、技术栈及开发环境三、主要功能&#xff08;一&#xff09;用户登录与注册&#xff08;二&#xff09;用户历史消息展示&#xff08;三&#xff09;在线用户实时聊天 四、结语 一、前言 在线聊天室作为一个虚拟社交…

springboot3.X版本集成mybatis遇到的问题

由于我本地springboot为3.x版本&#xff0c;如下图所示&#xff0c;最新版本 当我参照如下搜索的内容去集成mybatis的时候&#xff0c;会出现各种各样的报错 最根本的原因是搜出来的配置是参照springboot2.X版本&#xff0c;当我们使用springboot3.x版本之后&#xff0c;需要配…

图论篇--代码随想录算法训练营第五十八天打卡|拓扑排序,dijkstra(朴素版),dijkstra(堆优化版)精讲

拓扑排序 题目链接&#xff1a;117. 软件构建 题目描述&#xff1a; 某个大型软件项目的构建系统拥有 N 个文件&#xff0c;文件编号从 0 到 N - 1&#xff0c;在这些文件中&#xff0c;某些文件依赖于其他文件的内容&#xff0c;这意味着如果文件 A 依赖于文件 B&#xff0…

分布式中间件-分布式代理框架Codis和Twemproxy

文章目录 Codis框架架构图 Twemproxy框架Codis和Twemproxy对比设计目标功能特性使用场景结论 Codis框架 Codis是一个开源的分布式内存键值存储系统&#xff0c;它基于Redis并且提供了一个分布式的解决方案来扩展单一Redis实例的能力。Codis项目由豌豆荚团队开发&#xff0c;并…

【webpack4系列】webpack构建速度和体积优化策略(五)

文章目录 速度分析&#xff1a;使用 speed-measure-webpack-plugin体积分析&#xff1a;使用webpack-bundle-analyzer使用高版本的 webpack 和 Node.js多进程/多实例构建资源并行解析可选方案使用 HappyPack 解析资源使用 thread-loader 解析资源 多进程并行压缩代码方法一&…

基于C#+Mysql实现(界面)企业的设备管理系统

管理信息系统课程设计说明书 1 引言 企业的设备管理在企业的生产制造和管理过程之中意义比较重大&#xff0c;明确企业的设备的产权和维护成本对于企业的成本控制和财务管理之中起到了重要的作用。随着市场竞争的加剧&#xff0c;现代企业所处的市场环境发生了深刻的变革&…

【Mac】系统环境配置

常用工具 Navicat PJ版本&#xff1a;this Host切换器 SwitchHosts termius 一款好用的Linux服务器连接工具&#xff1a; termius 小飞机 dddd&#xff1a;&#x1fa9c; Git mac安装git有好多种方式&#xff0c;自带的xcode或者通过Homebrew来安装&#xff0c;本文的…

Java——类型转换

一、类型转换 1、介绍 类型转换分为自动类型转换和强制类型转换。 2、自动类型转换 自动类型转换是指在表达式中&#xff0c;当两种不同的数据类型组合在一起时&#xff0c;较小的数据类型会自动转换为较大的数据类型&#xff0c;这个过程是自动的&#xff0c;无需编程者手…

清华大佬自曝:接到了省烟草局的offer,我就拒掉了华为!结果华为立马给我申请了特殊涨薪,总包70w是烟草的2倍,这可如何是好?

《网安面试指南》http://mp.weixin.qq.com/s?__bizMzkwNjY1Mzc0Nw&mid2247484339&idx1&sn356300f169de74e7a778b04bfbbbd0ab&chksmc0e47aeff793f3f9a5f7abcfa57695e8944e52bca2de2c7a3eb1aecb3c1e6b9cb6abe509d51f&scene21#wechat_redirect 《Java代码审…

C:字符串函数(续)-学习笔记

穗 一些闲话&#xff1a; 最近玩了这款饿殍-明末千里行&#xff0c;不知大家是否有听过这款游戏&#xff0c;颇有感触&#xff01;&#xff01;&#xff01; 游戏中最让我难以忘怀的便是饿殍穗线的故事&#xff0c;生在如今时代的我之前无法理解杜甫在目睹人间悲剧时的心情&…

【网络原理】❤️Tcp 连接管理机制❤️ “三次握手” “四次挥手”的深度理解, 面试最热门的话题,没有之一, 保姆式教学 !!!

本篇会加入个人的所谓鱼式疯言 ❤️❤️❤️鱼式疯言:❤️❤️❤️此疯言非彼疯言 而是理解过并总结出来通俗易懂的大白话, 小编会尽可能的在每个概念后插入鱼式疯言,帮助大家理解的. &#x1f92d;&#x1f92d;&#x1f92d;可能说的不是那么严谨.但小编初心是能让更多人…

华为 HCIP 认证费用和报名资格

在当今竞争激烈的信息技术领域&#xff0c;华为 HCIP认证备受关注。它不仅能提升个人的技术实力与职业竞争力&#xff0c;也为企业选拔优秀人才提供了重要依据。以下将详细介绍华为 HCIP 认证的费用和报名资格。 一、HCIP 认证费用 华为HCIP认证的费用主要由考试费和培训费构成…

电气自动化入门01:电工基础

视频链接&#xff1a;1.1 电工知识&#xff1a;电工基础_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV1PJ41117PW?p2&vd_sourceb5775c3a4ea16a5306db9c7c1c1486b5 1.电能和电力系统 2.电工常用物理量及其应用 2.1电阻&#xff1a; 2.2电流&#xff1a; 2.3电压&…

【C++】入门基础(下)

Hi&#xff01;很高兴见到你~ 目录 7、引用 7.3 引用的使用&#xff08;实例&#xff09; 7.4 const引用 【第一分点】 【第二分点1】 【第二分点2】 7.5 指针和引用的关系&#xff08;面试点&#xff09; 8、inline 9、nullptr Relaxing Time&#xff01; ———…

系统 IO

"裸奔"层次&#xff1a;不带操作系统的编程 APP(应用程序) -------------------------------- Hardware(硬件) 特点&#xff1a;简单&#xff0c;应用程序直接操作硬件(寄存器) 缺点&#xff1a; 1. 搞应用开发的必须要了解硬件的实现细节&#xff0c;能够看懂原理图…

MyBatis 增删改查【后端 17】

MyBatis 增删改查 引言 MyBatis 是一个优秀的持久层框架&#xff0c;它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解用于配置和原始映射&#xff0c;将接口和 Java 的 POJOs (…

yolo训练出现Could not load library libcudnn_cnn_train.so.8问题及解决方法

问题场景&#xff1a; 训练yolov5或者yolov8时候会报错&#xff1a; Could not load library libcudnn_cnn_train.so.8. Error: /usr/local/cuda-12.1/lib64/libcudnn_cnn_train.so.8: uined symbol: _ZN5cudnn3cnn34layerNormFwd_execute_internal_implERKNS_7backend11Vari…

java技术栈介绍

Java技术栈是一个庞大而丰富的生态系统&#xff0c;它包含了从基础语言特性到高级框架、库和工具的整个集合。这个技术栈为开发者提供了构建各种类型应用&#xff08;包括企业级应用、Web应用、移动应用、大数据应用等&#xff09;所需的全部组件。以下是对Java技术栈的一个更详…

zip压缩包的格式不标准导致C++开源unzip.cpp解压失败问题的排查

目录 1、问题描述 2、初步排查 3、查看错误码512对应的含义 4、直接将解压zip包的函数拷贝过来,并将无法解压的zip取来,直接编写测试代码去调试解压过程,最终定位问题 4.1、调试开源unzip.cpp源码的准备工作 4.2、刚解压zip包中最顶层的文件夹就失败了 4.3、是不是zi…