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

news2024/9/27 17:34:55

文章目录

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

协议的概念

计算机之间的传输媒介是光信号和电信号。通过 “频率” 和 “强弱” 来表示 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.coloradmin.cn/o/2137655.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linux基础---07文件传输(网络和Win文件)

Linux文件传输地图如下&#xff0c;先选取你所需的场景&#xff0c;若你是需要Linux和Linux之间传输文件就查看SCP工具即可。 一.下载网站文件 前提是有网&#xff1a; 检查网络是否畅通命令&#xff1a;ping www.baidu.com&#xff0c;若有持续的返回值就说明网络畅通。Ctr…

请查收《网安问答秘籍》

在数字化日益普及的今天&#xff0c;网络安全威胁层出不穷&#xff0c;保护个人隐私和数据安全成为每个人的必修课。秘籍精选了最实用的网络安全问答&#xff0c;广大群众及时了解网络安全知识&#xff0c;提升网络安全意识&#xff0c;有效防范网络诈骗&#xff0c;确保个人信…

获取无人机经纬度是否在指定禁飞区内

1. 计算公式: (AB X AE ) * (CD X CE) >= 0 && (DA X DE ) * (BC X BE) >= 0 参考: 判断点是否在矩形框(多边形)内_qt opencv 判断一点是否在矩形内-CSDN博客 2.测试结果: 3.实现完整代码: #include<cstd

【系统规划与管理师】【案例分析】【考点】【答案篇】第7章 IT服务持续改进

【问题篇】☞【系统规划与管理师】【案例分析】【考点】【问题篇】第7章 IT服务持续改进 【移动端浏览】☞【系统规划与管理师】【案例分析】【模拟考题】章节考题汇总&#xff08;第7章&#xff09;&#xff08;答案篇&#xff09;&#xff08;共11个知识点&#xff09; 第7章…

在服务器上开Juypter Lab教程(远程访问)

在服务器上开Juypter Lab教程&#xff08;远程访问&#xff09; 文章目录 在服务器上开Juypter Lab教程&#xff08;远程访问&#xff09;一、安装anaconda1、安装anaconda2、提权限3、运行4、同意协议5、安装6、是否要自动初始化 conda7、结束8、检查 二、Anaconda安装Pytorch…

使用Docker挂载部署JAVA项目

用于需要使用Docker容器部署项目&#xff0c;但可能部署包需多次调整的场景&#xff0c;这种部署方式可以减少镜像制作的过程&#xff1b; 推荐几个使用Docker安装环境的文章&#xff1a; 1.Nocas: https://blog.csdn.net/weixin_44700323/article/details/140995859 2.Mysql: …

学习大数据DAY57 新的接口配置

作业  完成 API 接口和文件的接入, 并部署到生产调度平台, 每个任务最后至少 要有两条 不报错 的日志, 报错就驳回作业  作业不需要复制日志 API Appliation Program Interface 应用程序接口 > JSON 的地址 客户需求: 把 https://zhiyun.pub:9099/site/c-class…

从“看”到“管”:EasyCVR安防监控平台如何推动城市管理模式的转型升级

在21世纪的今天&#xff0c;随着城市化进程的加速推进&#xff0c;城市规模不断扩大&#xff0c;人口密集度显著增加&#xff0c;城市管理面临着前所未有的挑战。从公共安全、交通管理到环境保护、应急响应&#xff0c;每一个领域都对城市的治理能力和效率提出了更高要求。在这…

PowerShell install 一键部署Oracle23ai

Oracle23ai前言 Oracle Database 23ai Free 让您可以充分体验 Oracle Database 的能力,世界各地的企业都依赖它来处理关键任务工作负载。 Oracle Database Free 的资源限制为 2 个 CPU(前台进程)、2 GB 的 RAM 和 12 GB 的磁盘用户数据。该软件包不仅易于使用,还可轻松下载…

【LLM多模态】CogVideoX文生视频模型结构和训练过程

note 通过两阶段训练3D VAE&#xff0c;对视频进行压缩编码 第一阶段&#xff1a;在较低分辨率和较少帧数的视频上进行训练&#xff0c;学习压缩和重建视频的基本能力第二阶段&#xff1a;在更长的视频上训练&#xff0c;提高模型处理长视频的能力&#xff0c;同时保持帧与帧之…

JavaEE:文件内容操作练习(三)

文章目录 文件内容操作练习练习1练习2练习3 文件内容操作练习 练习1 扫描指定目录,并找到名称中包含指定字符的所有普通文件(不包含目录),并且后续询问用户是否要删除该文件. package javaEE.fileIO;import java.io.File; import java.util.Scanner;public class O {private…

数据结构基础讲解(八)——树和二叉树专项练习(上)

本文数据结构讲解参考书目&#xff1a; 通过网盘分享的文件&#xff1a;数据结构 C语言版.pdf 链接: https://pan.baidu.com/s/159y_QTbXqpMhNCNP_Fls9g?pwdze8e 提取码: ze8e 数据结构基础讲解&#xff08;七&#xff09;——数组和广义表专项练习-CSDN博客 个人主页&#x…

【初阶数据结构】详解树和二叉树(一) - 预备知识(我真的很想进步)

文章目录 前言1. 树1.1 树的概念1.2 树的相关概念1.3 树的表示1.4 树在实际中的运用 2. 二叉树2.1 二叉树的概念2.2 现实中的二叉树2.3 特殊的二叉树2.4 二叉树的性质2.5 二叉树概念和性质的一些习题 前言 初阶数据结构篇马上要迎来了一个新的成员&#xff0c;那就是"二叉…

这才是导师认可的论文 / 开题技术路线图

我是娜姐 迪娜学姐 &#xff0c;一个SCI医学期刊编辑&#xff0c;探索用AI工具提效论文写作和发表。 1. 技术路线图的常见框架结构 技术路线图根据研究内容和实验设计的不同&#xff0c;可以采用多种结构。以下是三种常见的技术路线图框架&#xff1a; 1.1 顺序式框架 适用领…

第十一周:机器学习笔记

第十一周周报 摘要Abstract机器学习1. 注意力机制&#xff08;下&#xff09;1.1 multi-head self-attention&#xff08;多头注意力机制&#xff09;1.2 Positional Encoding&#xff08;位置编码&#xff09;1.3 truncated self attention&#xff08;截断式注意力机制&#…

微软发布Windows Agent Arena 为生成式AI代理提供基准测试

使用生成式人工智能和大型语言模型来自动化和简化使用 PC 的人员的任务的情况持续增长。不过&#xff0c;人们也需要了解人工智能在完成任务方面的工作表现。本周微软研究院宣布&#xff0c;它已开发出一种专门用于在 Windows PC 上测试人工智能代理的基准。 微软在 GitHub 页面…

CHARLS数据库系列教程(2)---数据清洗、拼接和整理(1)

写在前面的话&#xff0c;本节内容实在太多了&#xff0c;只能做了一个小合集&#xff0c;分成2章来介绍。 CHARLS 是一项具备中国大陆 45 岁及以上人群代表性的追踪调查&#xff0c;旨在建设一个高质量的公共微观数据库&#xff0c;采集的信息涵盖社会经济状况和健康状况等多维…

Leetcode Hot 100刷题记录 -Day16(旋转图像)

旋转图像 问题描述&#xff1a; 给定一个 n n 的二维矩阵 matrix 表示一个图像。请你将图像顺时针旋转 90 度。 你必须在原地旋转图像&#xff0c;这意味着你需要直接修改输入的二维矩阵。请不要 使用另一个矩阵来旋转图像。 示例 1 输入&#xff1a;matrix [[1,2,3],[4,5,6]…

JavaScript - 异步编程

1. 前言 在 JavaScript 中&#xff0c;异步编程是一种处理需要等待操作&#xff08;如网络请求、文件读取或计时器&#xff09;的编程方式。由于 JavaScript 是单线程的&#xff0c;意味着它一次只能执行一个任务。异步编程允许你在等待某些操作完成时&#xff0c;继续执行其他…

河海大学《2020年+2021年827自动控制原理真题》 (完整版)

本文内容&#xff0c;全部选自自动化考研联盟的&#xff1a;《25届河海大学827自控考研资料》的真题篇。后续会持续更新更多学校&#xff0c;更多年份的真题&#xff0c;记得关注哦~ 目录 2020年复试真题 2021年初试真题 Part1&#xff1a;完整版真题 2020年复试真题 2021年…