一、低效率方式

/**
* 黏包、半包
*/
private static void buffExample2() {
/*
网络上传输多条数据给服务器,数据之间使用 \n 分隔。
但由于某种原因(多条数据合并发送会快)这些数据在接收时,被进行了重新组合,例如3条原始数据:
Hello world!\n
I'm Lihua.\n
How are you?\n
变成了2个 ByteBuffer,一个叫黏包,一个叫半包:
Hello world!\nI'm Lihua.\nHow a
re you?\n 如何使用代码将错乱的数据恢复成原来使用 \n 分割的样子
*/
// 模拟处理黏包、半包现象
ByteBuffer buf1 = ByteBuffer.allocate(50); // 接受到网络传输第一条消息
buf1.put("Hello world!\nI'm Lihua.\nHow a".getBytes(StandardCharsets.UTF_8));
System.out.println("第一次调用:");
msgSplit(buf1); // 调用处理方法
buf1.put("re you?\n".getBytes(StandardCharsets.UTF_8)); // 接受到网络传输第二条消息
System.out.println("第二次调用:");
msgSplit(buf1); // 调用处理方法 } private static void msgSplit(ByteBuffer buff) {
buff.flip(); // 切换成读模式,为下面的读取字符做准备
for (int i = 0; i < buff.limit(); i++) {
if (buff.get(i) == '\n') { // 判断 \n 所在位置
// 计算将要截取字符串的长度,包含 \n 符号在内
int len = i + 1 - buff.position(); // buff.position() 指针的位置
System.out.println("position:" + buff.position() + ",limit:" + buff.limit() + ",len:" + len);
ByteBuffer readBuff = ByteBuffer.allocate(len);
for (int j = 0; j < len; j++) {
readBuff.put(buff.get());
}
readBuff.flip();
System.out.println("读取到的消息:" + StandardCharsets.UTF_8.decode(readBuff));
}
}
System.out.println("切换成写模式!");
buff.compact(); // 切换成写模式,为后面消息写入做准备
}

NIO 缓冲区 ByteBuffer 之黏包和半包的更多相关文章

  1. Netty - 粘包和半包(上)

    在网络传输中,粘包和半包应该是最常出现的问题,作为 Java 中最常使用的 NIO 网络框架 Netty,它又是如何解决的呢?今天就让我们来看看. 定义 TCP 传输中,客户端发送数据,实际是把数据写 ...

  2. C#下利用封包、拆包原理解决Socket粘包、半包问题(新手篇)

    介于网络上充斥着大量的含糊其辞的Socket初级教程,扰乱着新手的学习方向,我来扼要的教一下新手应该怎么合理的处理Socket这个玩意儿. 一般来说,教你C#下Socket编程的老师,很少会教你如何解 ...

  3. 关于TCP封包、粘包、半包

    关于Tcp封包 很多朋友已经对此作了不少研究,也花费不少心血编写了实现代码和blog文档.当然也充斥着一些各式的评论,自己看了一下,总结一些心得. 首先我们学习一下这些朋友的心得,他们是: http: ...

  4. socket编程 TCP 粘包和半包 的问题及解决办法

    一般在socket处理大数据量传输的时候会产生粘包和半包问题,有的时候tcp为了提高效率会缓冲N个包后再一起发出去,这个与缓存和网络有关系. 粘包 为x.5个包 半包 为0.5个包 由于网络原因 一次 ...

  5. TCP的粘包、半包和Netty的处理

    参考文献:极客时间傅健老师的<Netty源码剖析与实战>Talk is cheap.show me the code! 什么是粘包和半包 在客户端发送数据时,实际是把数据写入到了TCP发送 ...

  6. 详说tcp粘包和半包

    tcp服务端和客户端建立连接后会长时间维持这个连接,用于互相传递数据,tcp是以流的方式传输数据的,就像一个水管里的水一样,从一头不断的流向另一头. 理想情况下,发送的数据包都是独立的, 现实要复杂一 ...

  7. Netty - 粘包和半包(下)

    上一篇介绍了粘包和半包及其通用的解决方案,今天重点来看一下 Netty 是如何实现封装成帧(Framing)方案的. 解码核心流程 之前介绍过三种解码器FixedLengthFrameDecoder. ...

  8. c# socket 解决粘包,半包

    处理原理: 半包:即一条消息底层分几次发送,先有个头包读取整条消息的长度,当不满足长度时,将消息临时缓存起来,直到满足长度再解码 粘包:两条完整/不完整消息粘在一起,一般是解码完上一条消息,然后再判断 ...

  9. TCP的组包、半包、粘包与分包

    一.概念 1)组包.简单的说就是tcp协议把过大的数据包分成了几个小的包传输,接收方要把同一组的数据包重新组合成一个完整的数据包. 2)半包.指接受方没有接受到一个完整的包,只接受了部分,这种情况主要 ...

  10. c# Socket通讯中关于粘包,半包的处理,加分割符

    using System; using System.Collections.Generic; using System.Text; using System.Net.Sockets; using S ...

随机推荐

  1. Springcloud gateway整合(集成)swagger2+finfe4j踩坑

    项目使用gateway代替之前的zuul网关,需要整合swagger,踩了许多坑之后终于解决问题,话不多说直接上代码 因为使用的是阿里的东西所以注册中心选择了nacos,它的配置这里就不贴了 spri ...

  2. Spring的IOC源码分析

    Spring IOC 容器源码分析 Spring 最重要的概念是 IOC 和 AOP,本篇文章其实就是要带领大家来分析下 Spring 的 IOC 容器.既然大家平时都要用到 Spring,怎么可以不 ...

  3. MapReduce原理——Shuffle机制

    在Map方法之后,Reduce方法之前的数据处理过程称之为Shuffle. Map方法输出的数据会获得对应的分区,进入环形缓冲区(缓冲区一半写索引,另一半写数据).数据达到缓冲区的80%会发生溢写.在 ...

  4. 072_关于Dataloader导入Record的创建时间及修改时间并允许owner是Inactive

    1.在User interface 中 启用 Enable "Set Audit Fields upon Record Creation" and "Update Rec ...

  5. Appium 入门

    Appium安装总体需要以下几个步骤: 安装JDK 官网www.oracle.com去下载安装,尽量下载JDK7及以上的版本.然后去设置环境变量: 在系统变量下新建变量JAVA_HOME变量值指向JD ...

  6. HttpURLConnection.openConnection状态码302

    今天根据URL,下载视频. new URL(url1).openConnection() 的时候,用HttpURLConnection接,出现302,以至于后面取不到流,无法读流. HttpURLCo ...

  7. react native 模拟机调试,debug菜单在哪

  8. signalR从外部服务中推送消息和全局参数的设置

    在前面的章节中,我们都是采用两方模式, 客户端 <-> 服务端,也就是说在这种情况下如果有第三方如果有通知的没有办法插足的,下面解决方案 1:和之前的代码一样,在index页面加一个客户端 ...

  9. gopher必读文章

    Getting Started with Go Programminghttps://www.programiz.com/golang/getting-startedHow to Write Go C ...

  10. Javascript格式化数字字符串,如手机号,银行卡号的格式化

    手机号13312341234转化成133 1234 1234 //方式一 function format_tel(tel){ tel = String(tel); return tel.replace ...