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

Openssl数据安全传输平台006:粘包的处理-代码框架及实现-TcpSocket.cpp

文章目录

  • 0. 代码仓库
  • 1. TCP通信粘包问题
  • 2. 粘包、拆包表现形式
    • 2.1 正常情况
    • 2.2 两个包合并成一个包
    • 2.3 出现了拆包
  • 3. 粘包的处理-参考仓库中的文件TcpSocket.cpp
    • 3.1 发送数据时候的处理
    • 3.2 接收数据时候的处理

0. 代码仓库

https://github.com/Chufeng-Jiang/OpenSSL_Secure_Data_Transmission_Platform

1. TCP通信粘包问题

tcp是以流动的方式传输数据,没有边界的一段数据。像打开自来水管一样,连成一片,没有边界。传输的最小单位为一个报 文段(segment)。

tcp Header中有个Options标识位,常见的标识为mss(Maximum Segment Size)指的是:连接层每次传输的数据有个最大限制MTU(Maximum Transmission Unit),一般是1500比特,超过这个量要分成多个报文段,mss则是这个最大限制减去TCP的header,光是要传输的数据的大小,一般为1460比特。换算成字节, 也就是180多字节。

tcp为提高性能,发送端会将需要发送的数据发送到缓冲区,等待缓冲区满了之后,再将缓冲中的数据发送到接收方。 同理,接收方也有缓冲区这样的机制,来接收数据。

发现,如果客户端连续不断的向服务端发送数据包时,服务端接收的数据会出现两个数据包粘在一起的情况,这就是TCP协议中经常会遇到的粘包以及拆包的问题。

2. 粘包、拆包表现形式

现在假设客户端向服务端连续发送了两个数据包,用packet1和packet2来表示,那么服务端收到的数据可以分为三种,现列举如下:

2.1 正常情况


第一种情况,接收端正常收到两个数据包,即没有发生拆包和粘包的现象,此种情况不在本文的讨论范围内。

2.2 两个包合并成一个包

第二种情况,接收端只收到一个数据包,由于TCP是不会出现丢包的,所以这一个数据包中包含了发送端发送的两个数据包的信息,这种现象即为粘包。这种情况由于接收端不知道这两个数据包的界限,所以对于接收端来说很难处理。
在这里插入图片描述

2.3 出现了拆包

第三种情况,这种情况有两种表现形式,如下图。接收端收到了两个数据包,但是这两个数据包要么是不完整的,要么就是多出来一块,这种情况即发生了拆包和粘包。在这里插入图片描述

3. 粘包的处理-参考仓库中的文件TcpSocket.cpp

3.1 发送数据时候的处理

添加4个字节的数据头,存储数据块的长度。

dataLen为发送原始数据的长度,在此基础上添加4个字节的长度,并开辟netdata空间用来存储数据。

int dataLen = sendData.size() + 4;
unsigned char *netdata = (unsigned char *)malloc(dataLen);

在发送的时候,需要从主机字节序转换为网络字节序。

  • 先求将原始数据转换成网络字节序的长度大小
    int netlen = htonl(sendData.size());

  • 再将原始数据的长度,拷贝到开辟的空间netdata前4个位置
    memcpy(netdata, &netlen, 4);

  • 最后将原始数据内容拷贝到开辟的空间netdata中第4个字节以后的位置
    memcpy(netdata + 4, sendData.data(), sendData.size());

int TcpSocket::sendMsg(string sendData, int timeout)
{// 返回0->没超时, 返回-1->超时int ret = writeTimeout(timeout);if (ret == 0){int writed = 0;int dataLen = sendData.size() + 4;// 添加的4字节作为数据头, 存储数据块长度unsigned char *netdata = (unsigned char *)malloc(dataLen);if (netdata == NULL){ret = MallocError;printf("func sckClient_send() mlloc Err:%d\n ", ret);return ret;}// 转换为网络字节序int netlen = htonl(sendData.size());memcpy(netdata, &netlen, 4);memcpy(netdata + 4, sendData.data(), sendData.size());// 没问题返回发送的实际字节数, 应该 == 第二个参数: dataLen// 失败返回: -1writed = writen(netdata, dataLen);......

3.2 接收数据时候的处理

  • 先读包头的4个字节并转换成主机字节序,就知道报文有多长。
    readn函数用于读取网络字节流的文件到缓存netdatalen空间中
    ret = readn(&netdatalen, 4); //读包头 4个字节
    int n = ntohl(netdatalen);

  • 根据包头中记录的数据大小申请内存, 接收数据,添加一个‘\0’结束符
    char* tmpBuf = (char *)malloc(n + 1);

  • 根据长度读数据
    ret = readn(tmpBuf, n);

string TcpSocket::recvMsg(int timeout)
{// 返回0 -> 没超时就接收到了数据, -1, 超时或有异常int ret = readTimeout(timeout); if (ret != 0){if (ret == -1 || errno == ETIMEDOUT){printf("readTimeout(timeout) err: TimeoutError \n");return string();}else{printf("readTimeout(timeout) err: %d \n", ret);return string();}}int netdatalen = 0;ret = readn(&netdatalen, 4); //读包头 4个字节if (ret == -1){printf("func readn() err:%d \n", ret);return string();}else if (ret < 4){printf("func readn() err peer closed:%d \n", ret);return string();}int n = ntohl(netdatalen);// 根据包头中记录的数据大小申请内存, 接收数据char* tmpBuf = (char *)malloc(n + 1);if (tmpBuf == NULL){ret = MallocError;printf("malloc() err \n");return NULL;}ret = readn(tmpBuf, n); //根据长度读数据if (ret == -1){printf("func readn() err:%d \n", ret);return string();}else if (ret < n){printf("func readn() err peer closed:%d \n", ret);return string();}tmpBuf[n] = '\0'; //多分配一个字节内容,兼容可见字符串 字符串的真实长度仍然为nstring data = string(tmpBuf);// 释放内存free(tmpBuf);return data;
}

相关文章:

Openssl数据安全传输平台006:粘包的处理-代码框架及实现-TcpSocket.cpp

文章目录 0. 代码仓库1. TCP通信粘包问题2. 粘包、拆包表现形式2.1 正常情况2.2 两个包合并成一个包2.3 出现了拆包 3. 粘包的处理-参考仓库中的文件TcpSocket.cpp3.1 发送数据时候的处理3.2 接收数据时候的处理 0. 代码仓库 https://github.com/Chufeng-Jiang/OpenSSL_Secure_…...

Java中在控制台读取字符

Scanner 是 Java 中的一个类&#xff0c;用于从各种输入源获取输入&#xff0c;如键盘、字符串、文件等。以下是如何使用 Scanner 的基本示例&#xff1a; javaimport java.util.Scanner; // 导入 Scanner 类public class Main { public static void main(String[] args) { Sca…...

PositiveSSL的泛域名SSL证书

PositiveSSL是Sectigo旗下的一个子品牌&#xff0c;致力于为全球用户提供优质、高效的SSL证书服务。PositiveSSL以Sectigo强大的品牌影响力和全球网络为基础&#xff0c;秉承“安全、可靠、高效”的服务理念&#xff0c;为各类网站提供全面的SSL证书解决方案。今天就随SSL盾小编…...

模拟 Junit 框架

需求 定义若干个方法&#xff0c;只要加了MyTest注解&#xff0c;就可以在启动时被触发执行 分析 定义一个自定义注解MyTest&#xff0c;只能注解方法&#xff0c;存活范围是一直都在定义若干个方法&#xff0c;只要有MyTest注解的方法就能在启动时被触发执行&#xff0c;没有这…...

瑞萨e2studio(27)----使用EZ-CUBE3烧录

瑞萨e2studio.27--使用EZ-CUBE3烧录 概述视频教学样品申请引脚配置EZ-CUBE3 仿真器开关设置对RA族MCU进行Flash编程蓝色 LED 指示灯的状态信息 概述 EZ-CUBE3&#xff08;CYRCNEZCUBE03&#xff09;是具有Flash存储器编程功能的片上调试仿真器&#xff0c;可以用于调试MCU程序…...

springBoot--web--函数式web

函数式web 前言场景给容器中放一个Bean&#xff1a;类型是 RouterFunction<ServerResponse>每个业务准备一个自己的handler使用集合的时候加注解请求的效果 前言 springmvc5.2 以后允许我们使用函数式的方式&#xff0c;定义web的请求处理流程 函数式接口 web请求处理的…...

react中hooks闭包

import React, { useState } from react;function Counter() {const [count, setCount] useState(0);return (<div><p>Count: {count}</p><button onClick{() > setCount(count 1)}>Increment</button></div>); }在上面的 React 组件…...

C++笔记之vector的初始化以及assign()方法

C笔记之vector的初始化以及assign()方法 —— 2023年4月15日 上海 code review 文章目录 C笔记之vector的初始化以及assign()方法代码——实践出真知0. 空的vector1. 花括号(initializer_list)——最推荐的初始化方法2. 花括号3. 圆括号花括号4. 圆括号5. 圆括号6. 指针花括号7…...

OSPF基础实验

一、实验拓扑 二、实验要求 1、按照图示配置 IP 地址 2、R1&#xff0c;R2&#xff0c;R3 运行 OSPF 使内网互通&#xff0c;所有接口(公网接口除外)全部宣告进 Area 0; 要求使用环回口作为 Router-id 3、业务网段不允许出现协议报文 4、R5 模拟互联网&#xff0c;内网通过…...

笔记本Charge与Vcore方案

一、笔记本Vcore方案 IMVP8/9:Intel Mobile Voltage Positionin VR12.5:就是指FIVR集成式调压模块(Haswell架构) PMIC:电源管理芯片(Power Management Integrated Circuits) 常见问题分析 1. 不开机,VCORE 短路 : 通常是因为Low side MOS短路造成.量测时可以先将MOS拿…...

error C2632: ‘char‘ followed by ‘char‘ is illegal

error C2632: char followed by char is illegal remove -stdc99...

MySql数据库实现注册登录及个人信息查询的数据库设计

前言: 数据库使用的是mysql 以下创建的表,实现以下功能: 用户1,账号admin,年龄20,关联3件商品 用户2,账号admin2,年龄30,关联2件商品(没有商品和用户1重复) 用户3,账号admin3,年龄50,关联2件商品(这两件商品均是用户1的其中两种) 登录查询对应数据的实现 1.创建用户表Users,并…...

C++-openssl-aes-cbc-pkcs5

PKCS#5填充是PKCS#7填充的一个子集&#xff0c;在PKCS#7填充时BlockSize为8的时候&#xff0c;PKCS#5与PKCS#7填充是一样的&#xff0c;在BlockSize不同时PKCS#5与PKCS#7填充是不同的。 PKCS#5填充是将数据填充到8的倍数&#xff0c; 填充后数据长度的计算公式&#xff1a; 定于…...

一个进程最多可以创建多少个线程基本分析

前言 ​话不多说&#xff0c;先来张脑图~ linux 虚拟内存知识回顾 虚拟内存空间长啥样 在 Linux 操作系统中&#xff0c;虚拟地址空间的内部又被分为内核空间和用户空间两部分&#xff0c;不同位数的系统&#xff0c;地址空间的范围也不同。比如最常见的 32 位和 64 位系统&…...

Swin Transformer V2 Scaling Up Capacity and Resolution(CVPR2022)

文章目录 AbstractIntroduction不稳定性问题下游任务需要的高分辨率问题解决内存问题- Related WorksLanguage networks and scaling upVision networks and scaling upTransferring across window / kernel resolution Swin Transformer V2Swin Transformer简介Scaling Up Mod…...

rust学习——字符串、字符串字面量、切片(slice)、字符串 slice

文章目录 字符串、字符串字面量、切片&#xff08;slice&#xff09;、字符串 slice01、字符串02、字符串字面量03、切片 &#xff08;slice&#xff09;04、字符串 slice 字符串 slice注意要点String 与 &str 的转换字符串深度剖析字符串 slice 作为函数参数例子001例子00…...

SolidWorks模型导入到Gazebo中

首先建立好solidworks模型&#xff0c;然后另存为stl格式&#xff0c; 导出为STL文件时&#xff0c;文件名最好不要是中文&#xff0c;并且要将后缀STL改为stl&#xff0c;否则Gazebo无法识别 这是我创建好的机器人充电桩模型&#xff1a; 尺寸是单位是mm&#xff1a; 135mm …...

使用CMake构建一个简单的C++项目

文章目录 一. 构建一个简单的项目二. 构建过程1. 创建程序源文件2. 编写CMakeList.txt文件3. 构建项目并编译源代码 附件 一. 构建一个简单的项目 最基本的CMake项目是从单个源代码文件构建的可执行文件。对于像这样的简单项目&#xff0c;只需要一个包含三个命令的CMakeLists…...

图论06-【无权无向】-图的遍历并查集Union Find-力扣695为例

文章目录 1. 代码仓库2. 思路2.1 UF变量设计2.2 UF合并两个集合2.3 查找当前顶点的父节点 find(element) 3. 完整代码 1. 代码仓库 https://github.com/Chufeng-Jiang/Graph-Theory 2. 思路 2.1 UF变量设计 parent数组保存着每个节点所指向的父节点的索引&#xff0c;初始值为…...

什么是卷积神经网络?解决了什么问题?

什么是卷积神经网络&#xff1f; 卷积神经网络&#xff08;Convolutional Neural Network&#xff0c;CNN&#xff09;是一种深度神经网络模型&#xff0c;主要用于图像识别、语音识别和自然语言处理等任务。它通过卷积层、池化层和全连接层来实现特征提取和分类。 解决了什么问…...

[特殊字符] 智能合约中的数据是如何在区块链中保持一致的?

&#x1f9e0; 智能合约中的数据是如何在区块链中保持一致的&#xff1f; 为什么所有区块链节点都能得出相同结果&#xff1f;合约调用这么复杂&#xff0c;状态真能保持一致吗&#xff1f;本篇带你从底层视角理解“状态一致性”的真相。 一、智能合约的数据存储在哪里&#xf…...

CTF show Web 红包题第六弹

提示 1.不是SQL注入 2.需要找关键源码 思路 进入页面发现是一个登录框&#xff0c;很难让人不联想到SQL注入&#xff0c;但提示都说了不是SQL注入&#xff0c;所以就不往这方面想了 ​ 先查看一下网页源码&#xff0c;发现一段JavaScript代码&#xff0c;有一个关键类ctfs…...

Mybatis逆向工程,动态创建实体类、条件扩展类、Mapper接口、Mapper.xml映射文件

今天呢&#xff0c;博主的学习进度也是步入了Java Mybatis 框架&#xff0c;目前正在逐步杨帆旗航。 那么接下来就给大家出一期有关 Mybatis 逆向工程的教学&#xff0c;希望能对大家有所帮助&#xff0c;也特别欢迎大家指点不足之处&#xff0c;小生很乐意接受正确的建议&…...

DIY|Mac 搭建 ESP-IDF 开发环境及编译小智 AI

前一阵子在百度 AI 开发者大会上&#xff0c;看到基于小智 AI DIY 玩具的演示&#xff0c;感觉有点意思&#xff0c;想着自己也来试试。 如果只是想烧录现成的固件&#xff0c;乐鑫官方除了提供了 Windows 版本的 Flash 下载工具 之外&#xff0c;还提供了基于网页版的 ESP LA…...

RNN避坑指南:从数学推导到LSTM/GRU工业级部署实战流程

本文较长&#xff0c;建议点赞收藏&#xff0c;以免遗失。更多AI大模型应用开发学习视频及资料&#xff0c;尽在聚客AI学院。 本文全面剖析RNN核心原理&#xff0c;深入讲解梯度消失/爆炸问题&#xff0c;并通过LSTM/GRU结构实现解决方案&#xff0c;提供时间序列预测和文本生成…...

大数据学习(132)-HIve数据分析

​​​​&#x1f34b;&#x1f34b;大数据学习&#x1f34b;&#x1f34b; &#x1f525;系列专栏&#xff1a; &#x1f451;哲学语录: 用力所能及&#xff0c;改变世界。 &#x1f496;如果觉得博主的文章还不错的话&#xff0c;请点赞&#x1f44d;收藏⭐️留言&#x1f4…...

今日学习:Spring线程池|并发修改异常|链路丢失|登录续期|VIP过期策略|数值类缓存

文章目录 优雅版线程池ThreadPoolTaskExecutor和ThreadPoolTaskExecutor的装饰器并发修改异常并发修改异常简介实现机制设计原因及意义 使用线程池造成的链路丢失问题线程池导致的链路丢失问题发生原因 常见解决方法更好的解决方法设计精妙之处 登录续期登录续期常见实现方式特…...

鸿蒙DevEco Studio HarmonyOS 5跑酷小游戏实现指南

1. 项目概述 本跑酷小游戏基于鸿蒙HarmonyOS 5开发&#xff0c;使用DevEco Studio作为开发工具&#xff0c;采用Java语言实现&#xff0c;包含角色控制、障碍物生成和分数计算系统。 2. 项目结构 /src/main/java/com/example/runner/├── MainAbilitySlice.java // 主界…...

招商蛇口 | 执笔CID,启幕低密生活新境

作为中国城市生长的力量&#xff0c;招商蛇口以“美好生活承载者”为使命&#xff0c;深耕全球111座城市&#xff0c;以央企担当匠造时代理想人居。从深圳湾的开拓基因到西安高新CID的战略落子&#xff0c;招商蛇口始终与城市发展同频共振&#xff0c;以建筑诠释对土地与生活的…...

云原生安全实战:API网关Kong的鉴权与限流详解

&#x1f525;「炎码工坊」技术弹药已装填&#xff01; 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 一、基础概念 1. API网关&#xff08;API Gateway&#xff09; API网关是微服务架构中的核心组件&#xff0c;负责统一管理所有API的流量入口。它像一座…...