socket解决半包、粘包问题

2023-10-30

  最近项目遇到socket服务端接收报文不全的问题,与其客户端约定的是报文长度+报文体。然而当客户端数据量大的时候,用分包发送,导致服务端报文日志接收不完整,于是想着先读出包体长度,再读出包体,不够就一直读,部分代码如下:

                    InputStream reader = socket.getInputStream();  
                    if (bytes.length < PACKET_HEAD_LENGTH) {  
                        byte[] head = new byte[PACKET_HEAD_LENGTH - bytes.length];  
                        int couter = reader.read(head);  
                        if (couter < 0) {  
                            continue;  
                        }  
                        bytes = mergebyte(bytes, head, 0, couter);  
                        if (couter < PACKET_HEAD_LENGTH) {  
                            continue;  
                        }  
                    }  
                    // 取7长度的字节子数组作为报文长度 
                    byte[] temp = new byte[0];  
                    temp = mergebyte(temp, bytes, 0, PACKET_HEAD_LENGTH);  
                    String templength = new String(temp);  
                    int bodylength = Integer.parseInt(templength);//包体长度  
                    if (bytes.length - PACKET_HEAD_LENGTH < bodylength) {//不够一个包  
                        byte[] body = new byte[bodylength + PACKET_HEAD_LENGTH - bytes.length];//剩下应该读的字节(凑一个包)  
                        int couter = reader.read(body);  
                        if (couter < 0) {  
                            continue;  
                        }  
                        bytes = mergebyte(bytes, body, 0, couter);  
                        if (couter < body.length) {  
                            continue;  
                        }  
                    }  
                    byte[] body = new byte[0];  
                    body = mergebyte(body, bytes, PACKET_HEAD_LENGTH, bytes.length);  
                    count++;  
                    System.out.println("server receive body:  " + count+new String(body));  
                    bytes = new byte[0];  
mergebyte方法如下:
        public byte[] mergebyte(byte[] a, byte[] b, int begin, int end) {  
            byte[] add = new byte[a.length + end - begin];  
            int i = 0;  
            for (i = 0; i < a.length; i++) {  
                add[i] = a[i];  
            }  
            for (int k = begin; k < end; k++, i++) {  
                add[i] = b[k];  
            }  
            return add;  
        }

 

这样server端接收到的都是完整的包。

 

转载于:https://www.cnblogs.com/yuyuchen/p/9090801.html

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

socket解决半包、粘包问题 的相关文章

随机推荐

  • js对象key使用变量命名

    JavaScript object对象key使用变量命名 let key name let obj key Bob name Bob
  • MySQL Geometry的使用 —— 地理空间类型Geometry

    注意 在投影坐标系中不同的投影标准有不同的单位 如常用到的投影标准 3857以米为单位 4326以度为单位 地理空间类型Geometry 一 Geometry数据类型有哪些 1 Geometry介绍 2 Geometry类型 二 Geome
  • vivado2020.2输出hello world

    首先打开vivado软件 新建工程 点击next 新建工程名 选择文件存放的位置 打上对勾 接下来 如图所示 配置如下环境 选中框选的内容 点击Next 具体的设置取决于板子 如图所示 点击finish完成相关的配置 如图 点击框选内容 新
  • 树莓派4b+mcp2515实现CAN总线通讯和系统编程(一.配置树莓派CAN总线接口)

    文章目录 前言 硬件连线 树莓派环境准备 启用树莓派ssh 启用mcp2515驱动 下载can utils工具 测试CAN通讯 开启CAN网卡 测试发送和接收 前言 树莓派本身是没有CAN通讯能力的 但他有mcp2515模块的驱动 可以通过
  • gitlab文档

    目录 1 原理 2 常用命令 3 web功能介绍 4 分支管理 1 原理 2 常用命令 git init 在本地新建一个repo 进入一个项目目录 执行git init 会初始化一个repo 并在当前文件夹下创建一个 git文件夹 git
  • 【leetcode.3】—— 无重复字符的最长子串

    原题链接 https leetcode cn com problems longest substring without repeating characters 题目 解析 该题使用滑动窗口的解法 窗口的右边界不断的向右移动 当窗口内的
  • Codeforces 1554C - Mikasa MEX

    input 5 3 5 4 6 3 2 69 696 123456 654321 output 4 3 0 640 530866 给出n m从n 0 gt n m中最小为出现的非负整数 int main int read while int
  • java ssh框架是什么_JAVA SSH框架介绍

    SSH为Struts Spring Hibernate的一个集成框架 是目前较流行的一种JAVA Web应用程序开源框架 Struts Structs是一个基于Sun J2EE平台的MVC框架爱 主要采用Servlet和JSP技术来实现的
  • java中子线程与主线程通信,java多线程编程学习(线程间通信)

    一 概要 线程是操作系统中独立的个体 但这些个体如果不经过特殊的处理就不能成为一个整体 线程间的通信就是成为整体的必用方案之一 可以说 使线程进行通信后 系统之间的交互性会更强大 在大大提高cpu利用率的同时还会使程序员对各线程任务在处理过
  • 卡尔曼滤波实战

    一 概述 这篇文章会使用一个形象化的最小例子说明卡尔曼滤波器各个公式的推导 如果你已经从纯数学公式推导过卡尔曼滤波器 那么这篇文章可以让你形象化地理解卡尔曼滤波器的精髓 即为什么利用 预测 gt 更新 的循环可以得到对系统状态的估计 如果你
  • APP开发项目流程详解,长知识了!

    APP的开发流程并不复杂 APP开发人员一般都包含着UI设计师 前端开发 后端开发 测试专员 产品经理等等 而根据开发人员的分工不同 可以把APP的开发项目流程分为三个阶段 需求阶段 开发阶段 发布阶段 具体流程如下 一 需求阶段 需求讨论
  • 服务器BMC知识介绍

    在介绍BMC之前需要了解一个概念 即平台管理 platform management 平台管理表示的是一系列的监视和控制功能 操作的对象是系统硬件 比如通过监视系统的温度 电压 风扇 电源等等 并做相应的调节工作 以保证系统处于健康的状态
  • 顺序表的建立及遍历

    读入n值及n个整数 建立顺序表并遍历输出 输入格式 读入n及n个整数 输出格式 输出n个整数 以空格分隔 最后一个数的后面没有空格 输入样例 4 3 10 20 78 输出样例 3 10 20 78 代码 include
  • 整型提升的讲解及举例应用

    文章目录 什么是整型提升 整型提升适合应用的情况 整型提升的目的 整形提升的原理 加深理解 小结 什么是整型提升 在C语言中 整型提升 integer promotion 是指当进行表达式运算时 比较小的整数类型会自动转换成较大的整数类型
  • wd 文件服务器客服电话,wd 云服务器

    wd 云服务器 内容精选 换一换 只有运行中的云服务器才允许用户登录 Windows操作系统用户名 Administrator 忘记密码 请先通过 重置密码 功能设置登录密码 重置密码 选中待重置密码的云耀云服务器 并选择 操作 列下的 重
  • SSTI模板注入小结

    文章目录 一 漏洞简述 二 flask模板注入 三 shrine 攻防世界 四 SSTI注入绕过 一 漏洞简述 1 SSTI Server Side Template Injection 服务器端模板注入 指的是一种攻击技术 攻击者通过向服
  • 怎么配置全局命令

    配置步骤 1 计算机 2 右键 属性 3 高级系统设置 4 环境变量 5 找到变量名为PATH 点编辑 用户变量 系统变量都可以 6 变量值添加上 你想打开的可执行文件所在的文件夹的路径 eg 我的迅雷应用thunder exe的地址为C
  • C知道是ChatGPT套壳?

    在网上 大家有传言C知道是ChatGPT套壳 那么是否属实呢 虽然目前未下结论 但是小编带大家来分析一下 虽然用中文问它它会说是csdn训练的 但是只要问它 Who are you 它就会回答 I am an AI language mod
  • 算法/论文笔记 Fluid Communities: A Competitive, Scalable and Diverse Community Detection Algorithm (2017)

    用于进行graph点的聚类 community detection 一个community内的点紧密地互相连接 community之间的点连接得很稀疏 1 主要算法 1 1 初始化 给定一张图G V E 其中V是顶点集 E表示边集 初始化的
  • socket解决半包、粘包问题

    最近项目遇到socket服务端接收报文不全的问题 与其客户端约定的是报文长度 报文体 然而当客户端数据量大的时候 用分包发送 导致服务端报文日志接收不完整 于是想着先读出包体长度 再读出包体 不够就一直读 部分代码如下 InputStrea