日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【Netty】TCP粘包和拆包

發布時間:2024/6/30 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【Netty】TCP粘包和拆包 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、前言

  前面已經基本上講解完了Netty的主要內容,現在來學習Netty中的一些可能存在的問題,如TCP粘包和拆包。

二、粘包和拆包

  對于TCP協議而言,當底層發送消息和接受消息時,都需要考慮TCP的粘包和拆包問題,一個完整的數據包可能會被TCP拆分為多個包發送,或者將多個小的數據包封裝成大的數據包發送。

  2.1 粘包和拆包基礎

  假設客戶端發送D1和D2兩個數據包至服務端,由于服務端每次讀取的數據大小時不確定的,因此,可能存在如下四種情況。

  ?

  ① 服務端分兩次讀取到數據包,分別為D1和D2,沒有粘包和拆包。

  ② 服務端一次讀取兩個數據包D1和D2,D1和D2黏合在一起,稱為TCP粘包。

  ③ 服務端一次讀取完整的D1數據包和D2數據包的一部分,第二次讀取D2剩余的部分,稱為TCP拆包。

  ④ 服務端一次讀取D1數據包的一部分,第二次讀取D1的剩余部分和D2數據包。

  可以看到,在底層發送數據時,可能會發生粘包和拆包,其原因大致有如下三種。

  ① 應用程序寫入字節大小大于套接字緩沖區大小。

  ② 進行MSS(Max Segment Size)大小的TCP分段。

  ③ 以太網幀的負載大于MTU(Maximum Transmission Unit)進行分片。

  由于底層的TCP協議無法理解上層的業務數據,所以底層無法保證數據不被拆分和重組,而為了解決粘包問題,業界主要的策略如下。

  ① 消息定長,如每個報文大小固定為200個字節,如果不夠,空格補位。

  ② 在包尾添加回車換行符進行分割,如FTP協議。

  ③ 將消息劃分為消息頭和消息體,消息頭中包含消息總長度的字段。

  2.2 TCP粘包示例

  下面通過一個示例展示未考慮粘包問題導致的異常。

  1. TimeServerHandler  

package com.hust.grid.leesf.chapter4;import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInboundHandlerAdapter;/*** Created by Leesf on 2017/6/28.*/ public class TimeServerHandler extends ChannelInboundHandlerAdapter {private int counter;@Overridepublic void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {ByteBuf buf = (ByteBuf) msg;byte[] req = new byte[buf.readableBytes()];buf.readBytes(req);String body = new String(req, "UTF-8").substring(0, req.length- System.getProperty("line.separator").length());System.out.println("The time server receive order : " + body+ " ; the counter is : " + ++counter);String currentTime = "QUERY TIME ORDER".equalsIgnoreCase(body) ? new java.util.Date(System.currentTimeMillis()).toString() : "BAD ORDER";currentTime = currentTime + System.getProperty("line.separator");ByteBuf resp = Unpooled.copiedBuffer(currentTime.getBytes());ctx.writeAndFlush(resp);}@Overridepublic void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {cause.printStackTrace();ctx.close();} }

  2. TimeServer

package com.hust.grid.leesf.chapter4;import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelInitializer; import io.netty.channel.ChannelOption; import io.netty.channel.EventLoopGroup; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.SocketChannel; import io.netty.channel.socket.nio.NioServerSocketChannel;/*** Created by Leesf on 2017/6/28.*/public class TimeServer {public void bind(int port) throws Exception {EventLoopGroup bossGroup = new NioEventLoopGroup();EventLoopGroup workerGroup = new NioEventLoopGroup();try {ServerBootstrap b = new ServerBootstrap();b.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class).option(ChannelOption.SO_BACKLOG, 1024).childHandler(new ChildChannelHandler());ChannelFuture f = b.bind(port).sync();f.channel().closeFuture().sync();} finally {bossGroup.shutdownGracefully();workerGroup.shutdownGracefully();}}private class ChildChannelHandler extends ChannelInitializer<SocketChannel> {@Overrideprotected void initChannel(SocketChannel arg0) throws Exception {arg0.pipeline().addLast(new TimeServerHandler());}}public static void main(String[] args) throws Exception {int port = 8080;if (args != null && args.length > 0) {try {port = Integer.valueOf(args[0]);} catch (NumberFormatException e) {// ignore }}new TimeServer().bind(port);} }

  3. TimeClientHandler  

package com.hust.grid.leesf.chapter4;import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.ChannelHandlerAdapter; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInboundHandlerAdapter;import java.util.logging.Logger;/*** Created by Leesf on 2017/6/28.*/public class TimeClientHandler extends ChannelInboundHandlerAdapter {private static final Logger logger = Logger.getLogger(TimeClientHandler.class.getName());private int counter;private byte[] req;public TimeClientHandler() {req = ("QUERY TIME ORDER" + System.getProperty("line.separator")).getBytes();}@Overridepublic void channelActive(ChannelHandlerContext ctx) {ByteBuf message = null;for (int i = 0; i < 100; i++) {message = Unpooled.buffer(req.length);message.writeBytes(req);ctx.writeAndFlush(message);}}@Overridepublic void channelRead(ChannelHandlerContext ctx, Object msg)throws Exception {ByteBuf buf = (ByteBuf) msg;byte[] req = new byte[buf.readableBytes()];buf.readBytes(req);String body = new String(req, "UTF-8");System.out.println("Now is : " + body + " ; the counter is : "+ ++counter);}@Overridepublic void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {cause.printStackTrace();ctx.close();} }

  4. TimeClient 

package com.hust.grid.leesf.chapter4;import io.netty.bootstrap.Bootstrap; import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelInitializer; import io.netty.channel.ChannelOption; import io.netty.channel.EventLoopGroup; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.SocketChannel; import io.netty.channel.socket.nio.NioSocketChannel;/*** Created by Leesf on 2017/6/28.*/public class TimeClient {public void connect(int port, String host) throws Exception {EventLoopGroup group = new NioEventLoopGroup();try {Bootstrap b = new Bootstrap();b.group(group).channel(NioSocketChannel.class).option(ChannelOption.TCP_NODELAY, true).handler(new ChannelInitializer<SocketChannel>() {@Overridepublic void initChannel(SocketChannel ch)throws Exception {ch.pipeline().addLast(new TimeClientHandler());}});ChannelFuture f = b.connect(host, port).sync();f.channel().closeFuture().sync();} finally {group.shutdownGracefully();}}public static void main(String[] args) throws Exception {int port = 8080;if (args != null && args.length > 0) {try {port = Integer.valueOf(args[0]);} catch (NumberFormatException e) {// ignore }}new TimeClient().connect(port, "127.0.0.1");} }

  分別運行服務器和客戶端,其中服務器的運行結果如下:  

The time server receive order : QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORD ; the counter is : 1 The time server receive order : QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER ; the counter is : 2 View Code

  客戶端的運行結果如下:  

Now is : BAD ORDER BAD ORDER; the counter is : 1

  可以看到服務端只接收到了兩條消息,一條消息包含了57條指令,另一條包含了43條指令,其與我們設計的100條單獨的消息不相符,發生了粘包。對于客戶端而言,其收到了兩條BAD ORDER,表示收到了兩條消息,counter應該為2,但是其counter為1,表示也發生了粘包。

  下面通過Netty的LineBasedFrameDecoder和String來解決粘包問題。

  1. TimeServerHandler 

package com.hust.grid.leesf.chapter4.fault;import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInboundHandlerAdapter;/*** Created by Leesf on 2017/6/28.*/ public class TimeServerHandler extends ChannelInboundHandlerAdapter {private int counter;@Overridepublic void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {ByteBuf buf = (ByteBuf) msg;byte[] req = new byte[buf.readableBytes()];buf.readBytes(req);String body = new String(req, "UTF-8").substring(0, req.length- System.getProperty("line.separator").length());System.out.println("The time server receive order : " + body+ " ; the counter is : " + ++counter);String currentTime = "QUERY TIME ORDER".equalsIgnoreCase(body) ? new java.util.Date(System.currentTimeMillis()).toString() : "BAD ORDER";currentTime = currentTime + System.getProperty("line.separator");ByteBuf resp = Unpooled.copiedBuffer(currentTime.getBytes());ctx.writeAndFlush(resp);}@Overridepublic void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {cause.printStackTrace();ctx.close();} }

  2. TimeServer 

package com.hust.grid.leesf.chapter4.fault;import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelInitializer; import io.netty.channel.ChannelOption; import io.netty.channel.EventLoopGroup; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.SocketChannel; import io.netty.channel.socket.nio.NioServerSocketChannel;/*** Created by Leesf on 2017/6/28.*/public class TimeServer {public void bind(int port) throws Exception {EventLoopGroup bossGroup = new NioEventLoopGroup();EventLoopGroup workerGroup = new NioEventLoopGroup();try {ServerBootstrap b = new ServerBootstrap();b.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class).option(ChannelOption.SO_BACKLOG, 1024).childHandler(new ChildChannelHandler());ChannelFuture f = b.bind(port).sync();f.channel().closeFuture().sync();} finally {bossGroup.shutdownGracefully();workerGroup.shutdownGracefully();}}private class ChildChannelHandler extends ChannelInitializer<SocketChannel> {@Overrideprotected void initChannel(SocketChannel arg0) throws Exception {arg0.pipeline().addLast(new TimeServerHandler());}}public static void main(String[] args) throws Exception {int port = 8080;if (args != null && args.length > 0) {try {port = Integer.valueOf(args[0]);} catch (NumberFormatException e) {// ignore }}new TimeServer().bind(port);} }

  3. TimeClientHandler 

package com.hust.grid.leesf.chapter4.correct;import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.ChannelHandlerAdapter; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInboundHandlerAdapter;import java.util.logging.Logger;/*** Created by Leesf on 2017/6/28.*/ public class TimeClientHandler extends ChannelInboundHandlerAdapter {private int counter;private byte[] req;public TimeClientHandler() {req = ("QUERY TIME ORDER" + System.getProperty("line.separator")).getBytes();}@Overridepublic void channelActive(ChannelHandlerContext ctx) {ByteBuf message = null;for (int i = 0; i < 100; i++) {message = Unpooled.buffer(req.length);message.writeBytes(req);ctx.writeAndFlush(message);}}@Overridepublic void channelRead(ChannelHandlerContext ctx, Object msg)throws Exception {String body = (String) msg;System.out.println("Now is : " + body + " ; the counter is : "+ ++counter);}@Overridepublic void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {cause.printStackTrace();ctx.close();} }

  4. TimeClient   

package com.hust.grid.leesf.chapter4.correct;import io.netty.bootstrap.Bootstrap; import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelInitializer; import io.netty.channel.ChannelOption; import io.netty.channel.EventLoopGroup; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.SocketChannel; import io.netty.channel.socket.nio.NioSocketChannel; import io.netty.handler.codec.LineBasedFrameDecoder; import io.netty.handler.codec.string.StringDecoder;/*** Created by Leesf on 2017/6/28.*/public class TimeClient {public void connect(int port, String host) throws Exception {EventLoopGroup group = new NioEventLoopGroup();try {Bootstrap b = new Bootstrap();b.group(group).channel(NioSocketChannel.class).option(ChannelOption.TCP_NODELAY, true).handler(new ChannelInitializer<SocketChannel>() {@Overridepublic void initChannel(SocketChannel ch)throws Exception {ch.pipeline().addLast(new LineBasedFrameDecoder(1024));ch.pipeline().addLast(new StringDecoder());ch.pipeline().addLast(new TimeClientHandler());}});ChannelFuture f = b.connect(host, port).sync();f.channel().closeFuture().sync();} finally {group.shutdownGracefully();}}public static void main(String[] args) throws Exception {int port = 8080;if (args != null && args.length > 0) {try {port = Integer.valueOf(args[0]);} catch (NumberFormatException e) {// ignore }}new TimeClient().connect(port, "127.0.0.1");} }

  分別運行服務端和客戶端,服務端結果如下: 

"D:\Program Files (x86)\Java\jdk1.8.0_65\bin\java" "-javaagent:D:\Program Files (x86)\JetBrains\IntelliJ IDEA 2017.1.4\lib\idea_rt.jar=62564:D:\Program Files (x86)\JetBrains\IntelliJ IDEA 2017.1.4\bin" -Dfile.encoding=UTF-8 -classpath "D:\Program Files (x86)\Java\jdk1.8.0_65\jre\lib\charsets.jar;D:\Program Files (x86)\Java\jdk1.8.0_65\jre\lib\deploy.jar;D:\Program Files (x86)\Java\jdk1.8.0_65\jre\lib\ext\access-bridge-64.jar;D:\Program Files (x86)\Java\jdk1.8.0_65\jre\lib\ext\cldrdata.jar;D:\Program Files (x86)\Java\jdk1.8.0_65\jre\lib\ext\dnsns.jar;D:\Program Files (x86)\Java\jdk1.8.0_65\jre\lib\ext\jaccess.jar;D:\Program Files (x86)\Java\jdk1.8.0_65\jre\lib\ext\jfxrt.jar;D:\Program Files (x86)\Java\jdk1.8.0_65\jre\lib\ext\localedata.jar;D:\Program Files (x86)\Java\jdk1.8.0_65\jre\lib\ext\nashorn.jar;D:\Program Files (x86)\Java\jdk1.8.0_65\jre\lib\ext\sunec.jar;D:\Program Files (x86)\Java\jdk1.8.0_65\jre\lib\ext\sunjce_provider.jar;D:\Program Files (x86)\Java\jdk1.8.0_65\jre\lib\ext\sunmscapi.jar;D:\Program Files (x86)\Java\jdk1.8.0_65\jre\lib\ext\sunpkcs11.jar;D:\Program Files (x86)\Java\jdk1.8.0_65\jre\lib\ext\zipfs.jar;D:\Program Files (x86)\Java\jdk1.8.0_65\jre\lib\javaws.jar;D:\Program Files (x86)\Java\jdk1.8.0_65\jre\lib\jce.jar;D:\Program Files (x86)\Java\jdk1.8.0_65\jre\lib\jfr.jar;D:\Program Files (x86)\Java\jdk1.8.0_65\jre\lib\jfxswt.jar;D:\Program Files (x86)\Java\jdk1.8.0_65\jre\lib\jsse.jar;D:\Program Files (x86)\Java\jdk1.8.0_65\jre\lib\management-agent.jar;D:\Program Files (x86)\Java\jdk1.8.0_65\jre\lib\plugin.jar;D:\Program Files (x86)\Java\jdk1.8.0_65\jre\lib\resources.jar;D:\Program Files (x86)\Java\jdk1.8.0_65\jre\lib\rt.jar;F:\01_Code\02_Idea\CoreInNetty\target\classes;C:\Users\lsf\.m2\repository\io\netty\netty-all\4.0.32.Final\netty-all-4.0.32.Final.jar;C:\Users\lsf\.m2\repository\com\fasterxml\jackson\core\jackson-core\2.6.3\jackson-core-2.6.3.jar;C:\Users\lsf\.m2\repository\com\fasterxml\jackson\core\jackson-databind\2.6.3\jackson-databind-2.6.3.jar;C:\Users\lsf\.m2\repository\com\fasterxml\jackson\core\jackson-annotations\2.6.0\jackson-annotations-2.6.0.jar" com.hust.grid.leesf.chapter4.correct.TimeServer The time server receive order : QUERY TIME ORDER ; the counter is : 1 The time server receive order : QUERY TIME ORDER ; the counter is : 2 The time server receive order : QUERY TIME ORDER ; the counter is : 3 The time server receive order : QUERY TIME ORDER ; the counter is : 4 The time server receive order : QUERY TIME ORDER ; the counter is : 5 The time server receive order : QUERY TIME ORDER ; the counter is : 6 The time server receive order : QUERY TIME ORDER ; the counter is : 7 The time server receive order : QUERY TIME ORDER ; the counter is : 8 The time server receive order : QUERY TIME ORDER ; the counter is : 9 The time server receive order : QUERY TIME ORDER ; the counter is : 10 The time server receive order : QUERY TIME ORDER ; the counter is : 11 The time server receive order : QUERY TIME ORDER ; the counter is : 12 The time server receive order : QUERY TIME ORDER ; the counter is : 13 The time server receive order : QUERY TIME ORDER ; the counter is : 14 The time server receive order : QUERY TIME ORDER ; the counter is : 15 The time server receive order : QUERY TIME ORDER ; the counter is : 16 The time server receive order : QUERY TIME ORDER ; the counter is : 17 The time server receive order : QUERY TIME ORDER ; the counter is : 18 The time server receive order : QUERY TIME ORDER ; the counter is : 19 The time server receive order : QUERY TIME ORDER ; the counter is : 20 The time server receive order : QUERY TIME ORDER ; the counter is : 21 The time server receive order : QUERY TIME ORDER ; the counter is : 22 The time server receive order : QUERY TIME ORDER ; the counter is : 23 The time server receive order : QUERY TIME ORDER ; the counter is : 24 The time server receive order : QUERY TIME ORDER ; the counter is : 25 The time server receive order : QUERY TIME ORDER ; the counter is : 26 The time server receive order : QUERY TIME ORDER ; the counter is : 27 The time server receive order : QUERY TIME ORDER ; the counter is : 28 The time server receive order : QUERY TIME ORDER ; the counter is : 29 The time server receive order : QUERY TIME ORDER ; the counter is : 30 The time server receive order : QUERY TIME ORDER ; the counter is : 31 The time server receive order : QUERY TIME ORDER ; the counter is : 32 The time server receive order : QUERY TIME ORDER ; the counter is : 33 The time server receive order : QUERY TIME ORDER ; the counter is : 34 The time server receive order : QUERY TIME ORDER ; the counter is : 35 The time server receive order : QUERY TIME ORDER ; the counter is : 36 The time server receive order : QUERY TIME ORDER ; the counter is : 37 The time server receive order : QUERY TIME ORDER ; the counter is : 38 The time server receive order : QUERY TIME ORDER ; the counter is : 39 The time server receive order : QUERY TIME ORDER ; the counter is : 40 The time server receive order : QUERY TIME ORDER ; the counter is : 41 The time server receive order : QUERY TIME ORDER ; the counter is : 42 The time server receive order : QUERY TIME ORDER ; the counter is : 43 The time server receive order : QUERY TIME ORDER ; the counter is : 44 The time server receive order : QUERY TIME ORDER ; the counter is : 45 The time server receive order : QUERY TIME ORDER ; the counter is : 46 The time server receive order : QUERY TIME ORDER ; the counter is : 47 The time server receive order : QUERY TIME ORDER ; the counter is : 48 The time server receive order : QUERY TIME ORDER ; the counter is : 49 The time server receive order : QUERY TIME ORDER ; the counter is : 50 The time server receive order : QUERY TIME ORDER ; the counter is : 51 The time server receive order : QUERY TIME ORDER ; the counter is : 52 The time server receive order : QUERY TIME ORDER ; the counter is : 53 The time server receive order : QUERY TIME ORDER ; the counter is : 54 The time server receive order : QUERY TIME ORDER ; the counter is : 55 The time server receive order : QUERY TIME ORDER ; the counter is : 56 The time server receive order : QUERY TIME ORDER ; the counter is : 57 The time server receive order : QUERY TIME ORDER ; the counter is : 58 The time server receive order : QUERY TIME ORDER ; the counter is : 59 The time server receive order : QUERY TIME ORDER ; the counter is : 60 The time server receive order : QUERY TIME ORDER ; the counter is : 61 The time server receive order : QUERY TIME ORDER ; the counter is : 62 The time server receive order : QUERY TIME ORDER ; the counter is : 63 The time server receive order : QUERY TIME ORDER ; the counter is : 64 The time server receive order : QUERY TIME ORDER ; the counter is : 65 The time server receive order : QUERY TIME ORDER ; the counter is : 66 The time server receive order : QUERY TIME ORDER ; the counter is : 67 The time server receive order : QUERY TIME ORDER ; the counter is : 68 The time server receive order : QUERY TIME ORDER ; the counter is : 69 The time server receive order : QUERY TIME ORDER ; the counter is : 70 The time server receive order : QUERY TIME ORDER ; the counter is : 71 The time server receive order : QUERY TIME ORDER ; the counter is : 72 The time server receive order : QUERY TIME ORDER ; the counter is : 73 The time server receive order : QUERY TIME ORDER ; the counter is : 74 The time server receive order : QUERY TIME ORDER ; the counter is : 75 The time server receive order : QUERY TIME ORDER ; the counter is : 76 The time server receive order : QUERY TIME ORDER ; the counter is : 77 The time server receive order : QUERY TIME ORDER ; the counter is : 78 The time server receive order : QUERY TIME ORDER ; the counter is : 79 The time server receive order : QUERY TIME ORDER ; the counter is : 80 The time server receive order : QUERY TIME ORDER ; the counter is : 81 The time server receive order : QUERY TIME ORDER ; the counter is : 82 The time server receive order : QUERY TIME ORDER ; the counter is : 83 The time server receive order : QUERY TIME ORDER ; the counter is : 84 The time server receive order : QUERY TIME ORDER ; the counter is : 85 The time server receive order : QUERY TIME ORDER ; the counter is : 86 The time server receive order : QUERY TIME ORDER ; the counter is : 87 The time server receive order : QUERY TIME ORDER ; the counter is : 88 The time server receive order : QUERY TIME ORDER ; the counter is : 89 The time server receive order : QUERY TIME ORDER ; the counter is : 90 The time server receive order : QUERY TIME ORDER ; the counter is : 91 The time server receive order : QUERY TIME ORDER ; the counter is : 92 The time server receive order : QUERY TIME ORDER ; the counter is : 93 The time server receive order : QUERY TIME ORDER ; the counter is : 94 The time server receive order : QUERY TIME ORDER ; the counter is : 95 The time server receive order : QUERY TIME ORDER ; the counter is : 96 The time server receive order : QUERY TIME ORDER ; the counter is : 97 The time server receive order : QUERY TIME ORDER ; the counter is : 98 The time server receive order : QUERY TIME ORDER ; the counter is : 99 The time server receive order : QUERY TIME ORDER ; the counter is : 100 View Code

  客戶端運行結果如下: 

"D:\Program Files (x86)\Java\jdk1.8.0_65\bin\java" "-javaagent:D:\Program Files (x86)\JetBrains\IntelliJ IDEA 2017.1.4\lib\idea_rt.jar=62637:D:\Program Files (x86)\JetBrains\IntelliJ IDEA 2017.1.4\bin" -Dfile.encoding=UTF-8 -classpath "D:\Program Files (x86)\Java\jdk1.8.0_65\jre\lib\charsets.jar;D:\Program Files (x86)\Java\jdk1.8.0_65\jre\lib\deploy.jar;D:\Program Files (x86)\Java\jdk1.8.0_65\jre\lib\ext\access-bridge-64.jar;D:\Program Files (x86)\Java\jdk1.8.0_65\jre\lib\ext\cldrdata.jar;D:\Program Files (x86)\Java\jdk1.8.0_65\jre\lib\ext\dnsns.jar;D:\Program Files (x86)\Java\jdk1.8.0_65\jre\lib\ext\jaccess.jar;D:\Program Files (x86)\Java\jdk1.8.0_65\jre\lib\ext\jfxrt.jar;D:\Program Files (x86)\Java\jdk1.8.0_65\jre\lib\ext\localedata.jar;D:\Program Files (x86)\Java\jdk1.8.0_65\jre\lib\ext\nashorn.jar;D:\Program Files (x86)\Java\jdk1.8.0_65\jre\lib\ext\sunec.jar;D:\Program Files (x86)\Java\jdk1.8.0_65\jre\lib\ext\sunjce_provider.jar;D:\Program Files (x86)\Java\jdk1.8.0_65\jre\lib\ext\sunmscapi.jar;D:\Program Files (x86)\Java\jdk1.8.0_65\jre\lib\ext\sunpkcs11.jar;D:\Program Files (x86)\Java\jdk1.8.0_65\jre\lib\ext\zipfs.jar;D:\Program Files (x86)\Java\jdk1.8.0_65\jre\lib\javaws.jar;D:\Program Files (x86)\Java\jdk1.8.0_65\jre\lib\jce.jar;D:\Program Files (x86)\Java\jdk1.8.0_65\jre\lib\jfr.jar;D:\Program Files (x86)\Java\jdk1.8.0_65\jre\lib\jfxswt.jar;D:\Program Files (x86)\Java\jdk1.8.0_65\jre\lib\jsse.jar;D:\Program Files (x86)\Java\jdk1.8.0_65\jre\lib\management-agent.jar;D:\Program Files (x86)\Java\jdk1.8.0_65\jre\lib\plugin.jar;D:\Program Files (x86)\Java\jdk1.8.0_65\jre\lib\resources.jar;D:\Program Files (x86)\Java\jdk1.8.0_65\jre\lib\rt.jar;F:\01_Code\02_Idea\CoreInNetty\target\classes;C:\Users\lsf\.m2\repository\io\netty\netty-all\4.0.32.Final\netty-all-4.0.32.Final.jar;C:\Users\lsf\.m2\repository\com\fasterxml\jackson\core\jackson-core\2.6.3\jackson-core-2.6.3.jar;C:\Users\lsf\.m2\repository\com\fasterxml\jackson\core\jackson-databind\2.6.3\jackson-databind-2.6.3.jar;C:\Users\lsf\.m2\repository\com\fasterxml\jackson\core\jackson-annotations\2.6.0\jackson-annotations-2.6.0.jar" com.hust.grid.leesf.chapter4.correct.TimeClient Now is : Wed Jun 28 16:12:25 CST 2017 ; the counter is : 1 Now is : Wed Jun 28 16:12:25 CST 2017 ; the counter is : 2 Now is : Wed Jun 28 16:12:25 CST 2017 ; the counter is : 3 Now is : Wed Jun 28 16:12:25 CST 2017 ; the counter is : 4 Now is : Wed Jun 28 16:12:25 CST 2017 ; the counter is : 5 Now is : Wed Jun 28 16:12:25 CST 2017 ; the counter is : 6 Now is : Wed Jun 28 16:12:25 CST 2017 ; the counter is : 7 Now is : Wed Jun 28 16:12:25 CST 2017 ; the counter is : 8 Now is : Wed Jun 28 16:12:25 CST 2017 ; the counter is : 9 Now is : Wed Jun 28 16:12:25 CST 2017 ; the counter is : 10 Now is : Wed Jun 28 16:12:25 CST 2017 ; the counter is : 11 Now is : Wed Jun 28 16:12:25 CST 2017 ; the counter is : 12 Now is : Wed Jun 28 16:12:25 CST 2017 ; the counter is : 13 Now is : Wed Jun 28 16:12:25 CST 2017 ; the counter is : 14 Now is : Wed Jun 28 16:12:25 CST 2017 ; the counter is : 15 Now is : Wed Jun 28 16:12:25 CST 2017 ; the counter is : 16 Now is : Wed Jun 28 16:12:25 CST 2017 ; the counter is : 17 Now is : Wed Jun 28 16:12:25 CST 2017 ; the counter is : 18 Now is : Wed Jun 28 16:12:25 CST 2017 ; the counter is : 19 Now is : Wed Jun 28 16:12:25 CST 2017 ; the counter is : 20 Now is : Wed Jun 28 16:12:25 CST 2017 ; the counter is : 21 Now is : Wed Jun 28 16:12:25 CST 2017 ; the counter is : 22 Now is : Wed Jun 28 16:12:25 CST 2017 ; the counter is : 23 Now is : Wed Jun 28 16:12:25 CST 2017 ; the counter is : 24 Now is : Wed Jun 28 16:12:25 CST 2017 ; the counter is : 25 Now is : Wed Jun 28 16:12:25 CST 2017 ; the counter is : 26 Now is : Wed Jun 28 16:12:25 CST 2017 ; the counter is : 27 Now is : Wed Jun 28 16:12:25 CST 2017 ; the counter is : 28 Now is : Wed Jun 28 16:12:25 CST 2017 ; the counter is : 29 Now is : Wed Jun 28 16:12:25 CST 2017 ; the counter is : 30 Now is : Wed Jun 28 16:12:25 CST 2017 ; the counter is : 31 Now is : Wed Jun 28 16:12:25 CST 2017 ; the counter is : 32 Now is : Wed Jun 28 16:12:25 CST 2017 ; the counter is : 33 Now is : Wed Jun 28 16:12:25 CST 2017 ; the counter is : 34 Now is : Wed Jun 28 16:12:25 CST 2017 ; the counter is : 35 Now is : Wed Jun 28 16:12:25 CST 2017 ; the counter is : 36 Now is : Wed Jun 28 16:12:25 CST 2017 ; the counter is : 37 Now is : Wed Jun 28 16:12:25 CST 2017 ; the counter is : 38 Now is : Wed Jun 28 16:12:25 CST 2017 ; the counter is : 39 Now is : Wed Jun 28 16:12:25 CST 2017 ; the counter is : 40 Now is : Wed Jun 28 16:12:25 CST 2017 ; the counter is : 41 Now is : Wed Jun 28 16:12:25 CST 2017 ; the counter is : 42 Now is : Wed Jun 28 16:12:25 CST 2017 ; the counter is : 43 Now is : Wed Jun 28 16:12:25 CST 2017 ; the counter is : 44 Now is : Wed Jun 28 16:12:25 CST 2017 ; the counter is : 45 Now is : Wed Jun 28 16:12:25 CST 2017 ; the counter is : 46 Now is : Wed Jun 28 16:12:25 CST 2017 ; the counter is : 47 Now is : Wed Jun 28 16:12:25 CST 2017 ; the counter is : 48 Now is : Wed Jun 28 16:12:25 CST 2017 ; the counter is : 49 Now is : Wed Jun 28 16:12:25 CST 2017 ; the counter is : 50 Now is : Wed Jun 28 16:12:25 CST 2017 ; the counter is : 51 Now is : Wed Jun 28 16:12:25 CST 2017 ; the counter is : 52 Now is : Wed Jun 28 16:12:25 CST 2017 ; the counter is : 53 Now is : Wed Jun 28 16:12:25 CST 2017 ; the counter is : 54 Now is : Wed Jun 28 16:12:25 CST 2017 ; the counter is : 55 Now is : Wed Jun 28 16:12:25 CST 2017 ; the counter is : 56 Now is : Wed Jun 28 16:12:25 CST 2017 ; the counter is : 57 Now is : Wed Jun 28 16:12:25 CST 2017 ; the counter is : 58 Now is : Wed Jun 28 16:12:25 CST 2017 ; the counter is : 59 Now is : Wed Jun 28 16:12:25 CST 2017 ; the counter is : 60 Now is : Wed Jun 28 16:12:25 CST 2017 ; the counter is : 61 Now is : Wed Jun 28 16:12:25 CST 2017 ; the counter is : 62 Now is : Wed Jun 28 16:12:25 CST 2017 ; the counter is : 63 Now is : Wed Jun 28 16:12:25 CST 2017 ; the counter is : 64 Now is : Wed Jun 28 16:12:25 CST 2017 ; the counter is : 65 Now is : Wed Jun 28 16:12:25 CST 2017 ; the counter is : 66 Now is : Wed Jun 28 16:12:25 CST 2017 ; the counter is : 67 Now is : Wed Jun 28 16:12:25 CST 2017 ; the counter is : 68 Now is : Wed Jun 28 16:12:25 CST 2017 ; the counter is : 69 Now is : Wed Jun 28 16:12:25 CST 2017 ; the counter is : 70 Now is : Wed Jun 28 16:12:25 CST 2017 ; the counter is : 71 Now is : Wed Jun 28 16:12:25 CST 2017 ; the counter is : 72 Now is : Wed Jun 28 16:12:25 CST 2017 ; the counter is : 73 Now is : Wed Jun 28 16:12:25 CST 2017 ; the counter is : 74 Now is : Wed Jun 28 16:12:25 CST 2017 ; the counter is : 75 Now is : Wed Jun 28 16:12:25 CST 2017 ; the counter is : 76 Now is : Wed Jun 28 16:12:25 CST 2017 ; the counter is : 77 Now is : Wed Jun 28 16:12:25 CST 2017 ; the counter is : 78 Now is : Wed Jun 28 16:12:25 CST 2017 ; the counter is : 79 Now is : Wed Jun 28 16:12:25 CST 2017 ; the counter is : 80 Now is : Wed Jun 28 16:12:25 CST 2017 ; the counter is : 81 Now is : Wed Jun 28 16:12:25 CST 2017 ; the counter is : 82 Now is : Wed Jun 28 16:12:25 CST 2017 ; the counter is : 83 Now is : Wed Jun 28 16:12:25 CST 2017 ; the counter is : 84 Now is : Wed Jun 28 16:12:25 CST 2017 ; the counter is : 85 Now is : Wed Jun 28 16:12:25 CST 2017 ; the counter is : 86 Now is : Wed Jun 28 16:12:25 CST 2017 ; the counter is : 87 Now is : Wed Jun 28 16:12:25 CST 2017 ; the counter is : 88 Now is : Wed Jun 28 16:12:25 CST 2017 ; the counter is : 89 Now is : Wed Jun 28 16:12:25 CST 2017 ; the counter is : 90 Now is : Wed Jun 28 16:12:25 CST 2017 ; the counter is : 91 Now is : Wed Jun 28 16:12:25 CST 2017 ; the counter is : 92 Now is : Wed Jun 28 16:12:25 CST 2017 ; the counter is : 93 Now is : Wed Jun 28 16:12:25 CST 2017 ; the counter is : 94 Now is : Wed Jun 28 16:12:25 CST 2017 ; the counter is : 95 Now is : Wed Jun 28 16:12:25 CST 2017 ; the counter is : 96 Now is : Wed Jun 28 16:12:25 CST 2017 ; the counter is : 97 Now is : Wed Jun 28 16:12:25 CST 2017 ; the counter is : 98 Now is : Wed Jun 28 16:12:25 CST 2017 ; the counter is : 99 Now is : Wed Jun 28 16:12:25 CST 2017 ; the counter is : 100 View Code

  可以看到此時客戶端和服務端的消息發送和接收都已經正常,不存在粘包問題。

  2.3 LineBasedFrameDecoder和StringDecoder解碼器說明

  LineBasedFrameDecoder會依次遍歷ByteBuf中的可讀字節,判斷是否有\n或者\r\n,其作為一行結束的標志,其是支持以換行符為結束標志的解碼器,支持攜帶結束符和非結束符的兩種解碼方式,同時支持配置最大單行長度,此時,如果連續讀取最大長度后仍未發現換行符,則會拋出異常,并忽略之前讀取的數據。

  StringDecoder將接收的對象轉化為字符串,然后繼續調用后面的handler,LineBasedFrameDecoder和StringDecoder組合起來使用用來解決按行切換的文本解碼器。并且Netty中提供了豐富的解碼器和編碼器供使用,具體的可以參見官方文檔。

三、總結

  本篇博文講解了TCP粘包,以及如何通過解碼器解決TCP粘包問題,當然,Netty除了提供按行切換的文本解碼器之外,還針對不同的應用場景,提供了其他豐富的解碼器。謝謝各位園友的觀看~

轉載于:https://www.cnblogs.com/leesf456/p/7069679.html

總結

以上是生活随笔為你收集整理的【Netty】TCP粘包和拆包的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。