解决TCP粘包问题

news2024/10/1 17:36:30

 粘包问题已经在上一篇博客中写到具体可以看-----------

以下是利用分包解决粘包问题的步骤:

  • 消息长度前缀: 在每个数据包前加入消息长度信息。

  • 定义协议格式: 明确定义通信协议的格式,包括消息头和消息体。

  • 封包: 将数据按照协议格式封装成完整的数据包。

  • 解包: 根据协议格式从接收到的字节流中解析出完整的数据包。

  • 处理残余数据: 保留可能存在的残余数据,并在下一次接收到数据时继续解析。

  • 错误处理: 考虑数据包丢失、损坏或乱序等特殊情况,实现相应的错误处理机制。

  • 测试和优化: 进行测试以确保系统在不同条件下正常运行,优化协议和分包处理性能

怎么解决粘包问题呢,其实借鉴一下tcp报文段的组成(分成TCP数据部分和TCP首部),我们也可以把发送的数据分为两个部分,一个是data,一个是data_len,这样有了data_len之后可以保证接收到完整的data数据后不再接受数据,这样就解决了粘包的问题。

看见如下图,client端发送的hi 和 jack没有粘在一块成hijack:

server:

int total_len=0;
    int len=0;  
    char buffer[1024];

    while ((len=read(client_sock,buffer+total_len,sizeof(buffer)-total_len))>0)
    {
        total_len+=len;
        while (total_len>=sizeof(int))
        {
            int data_len=*(int *)buffer;
            if(total_len>=sizeof(int)+data_len)
            {
                char data[1024];
                memmove(data,buffer+sizeof(int),data_len);
                data[data_len]='\0';
                std::cout<<"Received msg :"<<data<<std::endl;
                total_len-=sizeof(int)+data_len;
                memmove(buffer,buffer+sizeof(int)+data_len,total_len);
            }
            else{
                break;
            }
        }   
    }

 client:

std::string msg1="hi";
    std::string msg2="jack";

    char data1[256];
    *(int*)(data1)=msg1.length();
    int len=sizeof(int);

    memmove(data1+len,msg1.c_str(),msg1.length());


    if(write(client_sock,data1,len+msg1.length())==-1){
        std::cerr<<"Faild to write "<<std::endl;
        return -1;
    }

    char data2[256];
    *(int*)(data2)=msg2.length();
    int len2=sizeof(int);

    memmove(data2+len,msg2.c_str(),msg2.length());


    if(write(client_sock,data2,len2+msg2.length())==-1){
        std::cerr<<"Faild to write "<<std::endl;
        return -1;
    }

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

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

相关文章

Tensorflow2 GPU版本-极简安装方式

Tensorflow2 GPU版本-极简安装方式&#xff1a; 1、配置conda环境加速 https://wtl4it.blog.csdn.net/article/details/135723095https://wtl4it.blog.csdn.net/article/details/135723095 2、tensorflow-gpu安装 conda create -n STZZWANG_TF2 tensorflow-gpu2.0

kali安装LAMP和DVWA

LANMP简介 LANMP是指一组通常用来搭建动态网站或者服务器的开源软件&#xff0c;本身都是各自独立的程序&#xff0c;但是因为常被放在一起使用&#xff0c;拥有了越来越高的兼容度&#xff0c;共同组成了一个强大的Web应用程序平台。 L:指Linux&#xff0c;一类Unix计算机操作…

4G物联网LED智慧路灯杆显示屏产品介绍

4GLED显示屏是一种具有4G网络连接功能的LED显示屏。它可以通过4G网络连接到互联网&#xff0c;实现远程管理和控制&#xff0c;方便进行内容更新和管理。同时&#xff0c;4GLED显示屏具有高亮度、高清晰度和高对比度的特点&#xff0c;可以提供清晰明亮的图像和视频展示效果。它…

jdk17新特性——文本块(即多行的字符串)增强

目录 一、文本块(即多行的字符串)概述二、文本块(即多行的字符串)示例2.1、jdk17之前 多行字符串处理方式2.2、jdk17及以后版本 多行字符串处理方式2.3、注意事项 三、文本块(即多行的字符串)转义字符示例3.1、jdk17及以后版本 多行字符串的转义字符处理方式示例一3.2、jdk17及…

基于GPT3.5逆向 和 本地Bert-Vits2-2.3 的语音智能助手

文章目录 一、效果演示二、操作步骤三、架构解析 一、效果演示 各位读者你们好&#xff0c;我最近在研究一个语音助手的项目&#xff0c;是基于GPT3.5网页版的逆向和本地BertVits2-2.3 文字转语音&#xff0c;能实现的事情感觉还挺多&#xff0c;目前实现【无需翻墙&#xff0…

数据结构之线性表(一般的线性表)

前言 接下来就开始正式进入数据结构环节了&#xff0c;我们先从线性表开始。 线性表 线性表&#xff08;linear list&#xff09;也叫线性存储结构&#xff0c;即数据元素的逻辑结构为线性的数据表&#xff0c;它是数据结构中最简单和最常用的一种存储结构&#xff0c;专门存…

springboot快速开始

创建和配置 下面是创建和配置项目, 可以看看, 但是本文重点是怎么开web接口和连接数据库, 所以可以直接从gitee上下载我配好的 gitee 创建项目 java配置 idea里可以下载java maven maven用来帮你管理项目需要的包(库), 不过要下载快需要配镜像, 请查阅网络资料 添加依赖…

缓存高并发问题

Redis 做缓存虽减轻了 DBMS 的压力&#xff0c;减小了 RT&#xff0c;但在高并发情况下也是可能会出现各种问题的。 缓存穿透 当用户访问的数据既不在缓存也不在数据库中时&#xff0c;就会导致每个用户查询都会“穿透”缓存“直抵”数据库。这种情况就称为缓存穿透。当高度发…

处理Eclipse验证读条问题

打开Eclipse后下方一直读条加载验证&#xff0c;强迫症受不了。 依靠互联网自动加载失败&#xff0c;手动放入缺失的文件&#xff0c;我这里是mybatis的一个dtd文件缺失。 打开Eclipse-XML下的catalog&#xff0c;选择缺失的文件&#xff0c;保存。 可能需要重启Eclise

代码随想录刷题题Day41

刷题的第四十一天&#xff0c;希望自己能够不断坚持下去&#xff0c;迎来蜕变。&#x1f600;&#x1f600;&#x1f600; 刷题语言&#xff1a;C Day41 任务 ● 583. 两个字符串的删除操作 ● 72. 编辑距离 ● 编辑距离总结篇 1 两个字符串的删除操作 583. 两个字符串的删除…

详解线性分组码(linear code)

目录 一. 介绍 二. 线性分组码 三. 生成矩阵 四. 对偶编码 五. 校验矩阵 六. 陪集编码 七. 小结 一. 介绍 Low-density parity-check&#xff0c;简称LDPC码&#xff0c;翻译为低密度奇偶校验码。 我们所熟悉的LDPC码就是一个典型的线性分组码&#xff08;linear bloc…

HarmonyOS(十三)——详解自定义组件的生命周期

前言 自定义组件的生命周期回调函数用于通知用户该自定义组件的生命周期&#xff0c;这些回调函数是私有的&#xff0c;在运行时由开发框架在特定的时间进行调用&#xff0c;不能从应用程序中手动调用这些回调函数。 下图展示的是被Entry装饰的组件生命周期&#xff1a; 今…

大数据学习之Flink算子、了解DataStream API(基础篇一)

DataStream API &#xff08;基础篇&#xff09; 注&#xff1a; 本文只涉及DataStream 原因&#xff1a;随着大数据和流式计算需求的增长&#xff0c;处理实时数据流变得越来越重要。因此&#xff0c;DataStream由于其处理实时数据流的特性和能力&#xff0c;逐渐替代了DataSe…

macOS跨进程通信: Unix Domain Socket 创建实例

macOS跨进程通信: Unix Domain Socket 创建实例 一&#xff1a; 简介 Socket 是 网络传输的抽象概念。 一般我们常用的有Tcp Socket和 UDP Scoket&#xff0c; 和类Unix 系统&#xff08;包括Mac&#xff09;独有的 Unix Domain Socket&#xff08;UDX&#xff09;。 Tcp So…

基于SpringBoot Vue家政服务预约平台系统

大家好✌&#xff01;我是Dwzun。很高兴你能来阅读我&#xff0c;我会陆续更新Java后端、前端、数据库、项目案例等相关知识点总结&#xff0c;还为大家分享优质的实战项目&#xff0c;本人在Java项目开发领域有多年的经验&#xff0c;陆续会更新更多优质的Java实战项目&#x…

Midjourney 提示词入门 | 提示词格式 特点如何写好自己的提示词?进阶技巧

文章目录 1 Prompt格式2 文本提示词的基本要求3 好的文本提示词的特点 上一节我们初步了解了Midjourney的使用 那么在使用过程中最重要的是通过Prompt告知Midjourney怎么画 因而高效写Prompt非常重要~ 先来了解一下Prompt基本格式 1 Prompt格式 /imagine Text_prompt如下图…

【数据结构与算法】4.自主实现单链表的增删查改

&#x1f4da;博客主页&#xff1a;爱敲代码的小杨. ✨专栏&#xff1a;《Java SE语法》 ❤️感谢大家点赞&#x1f44d;&#x1f3fb;收藏⭐评论✍&#x1f3fb;&#xff0c;您的三连就是我持续更新的动力❤️ &#x1f64f;小杨水平有限&#xff0c;欢迎各位大佬指点&…

开始学习Vue2(脚手架,组件化开发)

一、单页面应用程序 单页面应用程序&#xff08;英文名&#xff1a;Single Page Application&#xff09;简 称 SPA&#xff0c;顾名思义&#xff0c;指的是一个 Web 网站中只有唯一的 一个 HTML 页面&#xff0c;所有的功能与交互都在这唯一的一个页面内完成。 二、vue-cli …

JVM虚拟机面试题

一.JVM组成 1.JVM是什么 2.什么是程序计数器 3.java堆 4.虚拟机栈 5.方法区 6.直接内存 二.类加载器 1.什么是类加载器,类加载器有哪些 2.双亲委派模型 3.类装载的执行过程 三.垃圾回收 1.对象什么时候可以被垃圾器回收 2.JVM垃圾回收算法 3.JVM分代回收 4.JVM有哪些垃圾回收…

vcenter7.0

Vcenter7.0简易详细安装图解 环境&#xff1a;Windows server 2016 镜像&#xff1a;VMware-VCSA-all-7.0.3-20395099.iso 1.前提配置一个静态IP地址&#xff08;192.168.80.120&#xff09;和关闭防火墙 2.配置一个dns&#xff08;这里做的是一个不加域的&#xff09; 第一步…