网络编程复习(八):Netty解决拆包粘包问题--定长方式
2017-09-29 17:40
465 查看
这里说道定长方式,个人觉得定长这种定义方式还是不够方便,因为当数据没有达到规定的长度的时候,你就必须用空格(或其他字符)补齐长度,否则这段不够的数据将会丢失。
在Netty中,分隔符与定长唯一的实现区别就是DelimiterBasedFrameDecoder(自定义分隔符)改为了FixedLengthFrameDecoder定长类。
注意:使用定长类,会有中文乱码问题,这里就要说说Netty的编解码技术了,下一章会说,同时除了这两种方式,还有第三张就是自定义传输协议,分为消息头和消息体,消息头会定义消息体的长度,这样就可以知道数据有多长,同样可以解决拆包粘包问题。
关于自定义协议可以看这篇文章,这里我就不说了
http://blog.csdn.net/zbw18297786698/article/details/53691915
client:
serverhandler类和clientHandler类与上一章一样,这里就不复制了。
server:
client端:
server端:
在Netty中,分隔符与定长唯一的实现区别就是DelimiterBasedFrameDecoder(自定义分隔符)改为了FixedLengthFrameDecoder定长类。
注意:使用定长类,会有中文乱码问题,这里就要说说Netty的编解码技术了,下一章会说,同时除了这两种方式,还有第三张就是自定义传输协议,分为消息头和消息体,消息头会定义消息体的长度,这样就可以知道数据有多长,同样可以解决拆包粘包问题。
关于自定义协议可以看这篇文章,这里我就不说了
http://blog.csdn.net/zbw18297786698/article/details/53691915
client:
package 网络编程_netty2; import io.netty.bootstrap.Bootstrap; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelInitializer; 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.DelimiterBasedFrameDecoder; import io.netty.handler.codec.FixedLengthFrameDecoder; import io.netty.handler.codec.string.StringDecoder; public class client { public static void main(String[] args) throws InterruptedException { EventLoopGroup worker = new NioEventLoopGroup(); Bootstrap bootstrap = new Bootstrap(); bootstrap.group(worker) .channel(NioSocketChannel.class) .handler(new ChannelInitializer<SocketChannel>() { @Override public void initChannel(SocketChannel ch) throws Exception { //ByteBuf buf = Unpooled.copiedBuffer("$_".getBytes()); //ch.pipeline().addLast(new DelimiterBasedFrameDecoder(1024, buf));//自定义分隔符 ch.pipeline().addLast(new FixedLengthFrameDecoder(5)); ch.pipeline().addLast(new StringDecoder());//设置字符串形式的解码 ch.pipeline().addLast(new ClientHandler()); } }); ChannelFuture f = bootstrap.connect("127.0.0.1", 8888).sync(); f.channel().writeAndFlush(Unpooled.wrappedBuffer("aaaaabbbbbb".getBytes())); f.channel().writeAndFlush(Unpooled.wrappedBuffer("bbbb".getBytes())); f.channel().writeAndFlush(Unpooled.wrappedBuffer("ccccccc".getBytes())); f.channel().closeFuture().sync(); worker.shutdownGracefully(); } }
serverhandler类和clientHandler类与上一章一样,这里就不复制了。
server:
package 网络编程_netty2; import io.netty.bootstrap.ServerBootstrap; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelInitializer; import io.netty.channel.EventLoopGroup; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.SocketChannel; import io.netty.channel.socket.nio.NioServerSocketChannel; import io.netty.handler.codec.DelimiterBasedFrameDecoder; import io.netty.handler.codec.FixedLengthFrameDecoder; import io.netty.handler.codec.string.StringDecoder; public class Server { private int port; public Server(int port){ this.port = port; } public void run()throws Exception{ EventLoopGroup boss = new NioEventLoopGroup(); EventLoopGroup workers = new NioEventLoopGroup(); ServerBootstrap bootstrap = new ServerBootstrap(); bootstrap.group(boss, workers) .channel(NioServerSocketChannel.class) .childHandler(new ChannelInitializer<SocketChannel>() { @Override public void initChannel(SocketChannel ch) throws Exception { //ByteBuf buf = Unpooled.copiedBuffer("$_".getBytes()); //ch.pipeline().addLast(new DelimiterBasedFrameDecoder(1024, buf)); ch.pipeline().addLast(new FixedLengthFrameDecoder(5)); ch.pipeline().addLast(new StringDecoder()); ch.pipeline().addLast(new ServerHandler()); } }); ChannelFuture f = bootstrap.bind(port).sync(); f.channel().closeFuture().sync(); workers.shutdownGracefully(); boss.shutdownGracefully(); } public static void main(String[] args) throws Exception { new Server(8888).run(); } }注意:我client端发送的数据是不够长度的,因此会造成数据丢失,用空格补全就可以了,这里就不贴了,下面看下输出内容:
client端:
hello hello hello hello
server端:
aaaaa bbbbb bbbbb ccccc
相关文章推荐
- 网络编程复习(七):Netty解决拆包粘包问题--分隔符方式
- Android网络编程之使用get方式向服务端提交数据和乱码问题的解决
- Java网络编程获取网页的乱码问题解决
- iOS网络编程-解决iCloud文档存储过程中文档冲突问题
- Flash网络编程安全沙箱问题隆重解决 (转)
- iOS网络编程-解决iCloud文档存储过程中文档冲突问题
- 不同database排序方式,不同语言,如何解决国际化编程问题
- window下udp网络编程存在的问题-socket error 10054解决方法
- iOS网络编程-解决iCloud文档存储过程中文档冲突问题
- 解决C#网络通信编程的阻塞问题
- C# 网络编程之webBrowser乱码问题及解决知识
- 解决在编程方式下无法访问Spark Master问题
- 解决java网络编程IPv6带来的问题方法
- 解决java网络编程IPv6问题
- iOS网络编程-解决iCloud文档存储过程中文档冲突问题
- Flash网络编程安全沙箱问题隆重解决
- 解决java网络编程IPv6问题
- java 网络编程【7】 如何检测和解决端口冲突问题?
- C# 网络编程之豆瓣OAuth2.0认证详解和遇到的各种问题及解决
- Windows下用PostThreadMessage解决网络编程中线程间通讯的问题