一、低效率方式

/**
* 黏包、半包
*/
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. 如何用adb连接android手机

    如何用adb连接android手机 以下为手机"root"情况下操作....手机没root请拉到笔记最后,有解决方法 利用adb来连接手机, 有两种方式: wifi usb 通过w ...

  2. ELK分布式日志系统的搭建

    前言 ELK即分别为ElasticSearch.Logstash(收集.分析.过滤日志的工具).Kibana(es的可视化工具),其主要工作原理就是由不同机器上的logstash收集日志后发送给es, ...

  3. IDEA的常用快捷键和文档注释

    IDEA的常用快捷键 Alt + 回车 导入包,自动修正 Ctrl + N 查找类 Ctrl + Shift + N 查找文件 Ctrl + Alt + N 格式化代码 Ctrl + Alt + O ...

  4. mysql报错This function has none of DETERMINISTIC. NO SOL or READS SOL DATA...

    是因为 存储过程/存储函数在创建时 与 开启慢查询日志冲突了 解决冲突: 临时解决:开启log_bin_trust_function_creators show variables like '%lo ...

  5. js中各种导出和导入

        exports和module exports的区别: exports是module exports的地址引用 export和export default的区别: export和export d ...

  6. ubuntu测网速speedometer

    下载安装speedometer sudo apt-get install speedometer 查询需要测速的网卡 ifconfig 测速 speedometer -rx enp2s0 执行效果图如 ...

  7. VS2015+QT5.10项目中文乱码

    解决:文件-高级保存选项,选择utf-8编码.

  8. 用“餐厅打包”的故事说明白Python里面的自定义函数

    注:博主并非Python专业程序员,年龄12岁,Python龄不到1岁,才疏学浅,如有错误还请大佬指教! 希望能通过本专栏帮助到一些Python小白! 嗨~大家好!上篇博文咱们说了,万一有一些上万行才 ...

  9. 关于WPF的圆角

    失败案例 <Border CornerRadius="3" Width="100" Height="100"> <Stac ...

  10. 入坑winpdb-1.4.8

    这几天莫名的不能在docker中使用winpdb-1.4.8调试,把容器重新安装了也不行,跟踪调试以后发现原因是容器中使用pycryptodemo作为rpdb2的加密库,加密向量IV需要以bytes类 ...