NIO 缓冲区 ByteBuffer 之黏包和半包
一、低效率方式
/**
* 黏包、半包
*/
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 之黏包和半包的更多相关文章
- Netty - 粘包和半包(上)
在网络传输中,粘包和半包应该是最常出现的问题,作为 Java 中最常使用的 NIO 网络框架 Netty,它又是如何解决的呢?今天就让我们来看看. 定义 TCP 传输中,客户端发送数据,实际是把数据写 ...
- C#下利用封包、拆包原理解决Socket粘包、半包问题(新手篇)
介于网络上充斥着大量的含糊其辞的Socket初级教程,扰乱着新手的学习方向,我来扼要的教一下新手应该怎么合理的处理Socket这个玩意儿. 一般来说,教你C#下Socket编程的老师,很少会教你如何解 ...
- 关于TCP封包、粘包、半包
关于Tcp封包 很多朋友已经对此作了不少研究,也花费不少心血编写了实现代码和blog文档.当然也充斥着一些各式的评论,自己看了一下,总结一些心得. 首先我们学习一下这些朋友的心得,他们是: http: ...
- socket编程 TCP 粘包和半包 的问题及解决办法
一般在socket处理大数据量传输的时候会产生粘包和半包问题,有的时候tcp为了提高效率会缓冲N个包后再一起发出去,这个与缓存和网络有关系. 粘包 为x.5个包 半包 为0.5个包 由于网络原因 一次 ...
- TCP的粘包、半包和Netty的处理
参考文献:极客时间傅健老师的<Netty源码剖析与实战>Talk is cheap.show me the code! 什么是粘包和半包 在客户端发送数据时,实际是把数据写入到了TCP发送 ...
- 详说tcp粘包和半包
tcp服务端和客户端建立连接后会长时间维持这个连接,用于互相传递数据,tcp是以流的方式传输数据的,就像一个水管里的水一样,从一头不断的流向另一头. 理想情况下,发送的数据包都是独立的, 现实要复杂一 ...
- Netty - 粘包和半包(下)
上一篇介绍了粘包和半包及其通用的解决方案,今天重点来看一下 Netty 是如何实现封装成帧(Framing)方案的. 解码核心流程 之前介绍过三种解码器FixedLengthFrameDecoder. ...
- c# socket 解决粘包,半包
处理原理: 半包:即一条消息底层分几次发送,先有个头包读取整条消息的长度,当不满足长度时,将消息临时缓存起来,直到满足长度再解码 粘包:两条完整/不完整消息粘在一起,一般是解码完上一条消息,然后再判断 ...
- TCP的组包、半包、粘包与分包
一.概念 1)组包.简单的说就是tcp协议把过大的数据包分成了几个小的包传输,接收方要把同一组的数据包重新组合成一个完整的数据包. 2)半包.指接受方没有接受到一个完整的包,只接受了部分,这种情况主要 ...
- c# Socket通讯中关于粘包,半包的处理,加分割符
using System; using System.Collections.Generic; using System.Text; using System.Net.Sockets; using S ...
随机推荐
- Flask + PyInstaller = 客户端
Flask + PyInstaller = 客户端 有些特殊情况需要开发客户端,Python有几个常用的几个GUI框架,如 PyQt.wxPython等 但使用这些GUI框架往往界面比较丑,而且GUI ...
- ubuntu安装cuda、cudnn和nvidia-docker
目录 安装前的工作 要安装的cuda和cudnn版本说明 安装cuda 检查cuda的安装情况 安装cudnn 安装nvidia-docker 在红米book14上的实践 本文参考自Ubuntu18. ...
- 查看nohup.out 日志文件
1.查看实时日志: tail -f nohup.out 2.查看实时日志并检索关键字: tail -f nohup.out | grep "关键字" 3.查看文件最后100行日志: ...
- react-router V6踩坑
useRoutes() may be used only in the context of a <Router> component.需要将BrowserRouter放到外层,放到APP ...
- jmeter接口之json提取器应用
在接口测试中有一个这样的场景:业务接口需要用到登录token:下个接口需要用到前个接口返回值作为参数,该怎么实现? 首先先看下登录.业务接口,本文用的jmeter版本为5.4.1 一.json提取器设 ...
- Spyder无法使用搜狗输入中文的解决办法
Ubuntu 18.04 LTS系统下,spyder4编辑器无法使用搜狗输入中文.系统输入法为fcitx+搜狗拼音,chrome浏览器无此问题.网上答案: Spyder (以及其他PyQt程序) 无法 ...
- 登录注册的小项目对比.Net Core与 .Net Framework的一些区别
一.需求: 1.功能只有登录.注册. 二.架构: 1.分别为 UserSys.IServices:主要有实体和对实体的配置,还有对实体的操作接口 UserSys.Services :主要是对自ISer ...
- mysql5.7 不兼容问题
通过navicat工具导入psc数据库备份文件,报错如下,mysql版本5.7 执行如下语句不通过 DROP TABLE IF EXISTS `guard_user`; CREATE TABLE `g ...
- Windows下的挖矿木马查杀
MS016小组(原创) 上一篇文章 简单讲了一下挖矿木马 大概流程 文章地址: https://www.cnblogs.com/ms016/articles/7978880.html 今天讲分析一个 ...
- Windows 分辨率改变引起WPF的适应问题
系统分辨率变化,全屏WPF的UI出现没更新和白底之类的现象记录. 您可以使用SystemParameters.WorkArea.最初设置MainWindow的MaxHeight. 在MainWindo ...