这篇文章主要讲解了“TCP粘包问题介绍与Netty中message定义”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“TCP粘包问题介绍与Netty中message定义”吧!
假设客户端分别发送了两个数据包D1与D2,由于服务端一次读取到的字节数时不确定的,因此有可能出现一下5种情况:
服务端分两次读取到了两个独立的数据包,分别是D1与D2,没有粘包与拆包;
服务端一次接收了两个数据包,D1与D2粘合在一起,被称为TCP粘包;
服务端分两次读取到了两个数据包,第一次读取到了D2包的一部分内容,第二次读取到了D2包的剩余内容与完整的D1包内容,被称为TCP拆包;
服务端分两次读取到了两个数据包,第一次读取到了完整的D2包和D1包的一部分内容,第二次读取到了D1包的剩余内容;
如果服务器的TCP接收滑动窗口非常小,而数据包D1与D2比较大,服务端分多次才能将D1与D2包接收完,这期间会发生多次拆包。
1.2、粘包问题解决策略
消息定长。例如固定每个报文的大小为100个字节,如果不够,空位补空格;
将详细分为消息头与消息体,消息头中包含消息总长度(或消息体长度)的字段;
在包尾增加回车换行符进行分割;
Netty协议栈中的消息分为两部分:
消息头
消息体
/**
* 16进制字符串 与 byte数组 相互转换工具类
*/
public class HexUtils {
private static final char[] HEXES = {
'0', '1', '2', '3',
'4', '5', '6', '7',
'8', '9', 'a', 'b',
'c', 'd', 'e', 'f'
};
/**
* byte数组 转换成 16进制小写字符串
*/
public static String bytes2Hex(byte[] bytes) {
if (bytes == null || bytes.length == 0) {
return null;
}
StringBuilder hex = new StringBuilder();
for (byte b : bytes) {
hex.append(HEXES[(b >> 4) & 0x0F]);
hex.append(HEXES[b & 0x0F]);
}
return hex.toString();
}
/**
* 16进制字符串 转换为对应的 byte数组
*/
public static byte[] hex2Bytes(String hex) {
if (hex == null || hex.length() == 0) {
return null;
}
char[] hexChars = hex.toCharArray();
byte[] bytes = new byte[hexChars.length / 2]; // 如果 hex 中的字符不是偶数个, 则忽略最后一个
for (int i = 0; i < bytes.length; i++) {
bytes[i] = (byte) Integer.parseInt("" + hexChars[i * 2] + hexChars[i * 2 + 1], 16);
}
return bytes;
}
}
---------------------
作者:xietansheng
原文:https://blog.csdn.net/xietansheng/article/details/88421655
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
import java.io.ByteArrayOutputStream;
import java.io.Closeable;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
/**
* Base64 转换工具
*/
public class Base64Utils {
/**
* byte数组 转换为 Base64字符串
*/
public static String encode(byte[] data) {
return new BASE64Encoder().encode(data);
}
/**
* Base64字符串 转换为 byte数组
*/
public static byte[] decode(String base64) {
try {
return new BASE64Decoder().decodeBuffer(base64);
} catch (IOException e) {
e.printStackTrace();
}
return new byte[0];
}
/**
* 把文件内容编码为 Base64字符串, 只能编码小文件(例如文本、图片等)
*/
public static String encodeFile(File file) throws Exception {
InputStream in = null;
ByteArrayOutputStream bytesOut = null;
try {
in = new FileInputStream(file);
bytesOut = new ByteArrayOutputStream((int) file.length());
byte[] buf = new byte[1024];
int len = -1;
while ((len = in.read(buf)) != -1) {
bytesOut.write(buf, 0, len);
}
bytesOut.flush();
return encode(bytesOut.toByteArray());
} finally {
close(in);
close(bytesOut);
}
}
/**
* 把 Base64字符串 转换为 byte数组, 保存到指定文件
*/
public static void decodeFile(String base64, File file) throws Exception {
OutputStream fileOut = null;
try {
fileOut = new FileOutputStream(file);
fileOut.write(decode(base64));
fileOut.flush();
} finally {
close(fileOut);
}
}
private static void close(Closeable c) {
if (c != null) {
try {
c.close();
} catch (IOException e) {
// nothing
}
}
}
}
感谢各位的阅读,以上就是“TCP粘包问题介绍与Netty中message定义”的内容了,经过本文的学习后,相信大家对TCP粘包问题介绍与Netty中message定义这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是亿速云,小编将为大家推送更多相关知识点的文章,欢迎关注!
亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。
原文链接:https://my.oschina.net/u/4083311/blog/3068280