您好,登錄后才能下訂單哦!
這篇文章主要講解了“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定義這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。