Netty解决粘包问题(1) 自定义分隔符

原创 2016年08月30日 21:37:57

见如下代码


Client.java
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;
import io.netty.handler.codec.string.StringEncoder;

public class Client {

    public static void main(String[] args) throws Exception {

        EventLoopGroup group = new NioEventLoopGroup();

        Bootstrap b = new Bootstrap();
        b.group(group)
         .channel(NioSocketChannel.class)
         .handler(new ChannelInitializer<SocketChannel>() {
            @Override
            protected void initChannel(SocketChannel sc) throws Exception {
                //
                ByteBuf buf = Unpooled.copiedBuffer("$_".getBytes());
                sc.pipeline().addLast(new DelimiterBasedFrameDecoder(1024, buf));
                sc.pipeline().addLast(new StringDecoder());
                sc.pipeline().addLast(new ClientHandler());
            }
        });

        ChannelFuture cf = b.connect("127.0.0.1", 8765).sync();

        cf.channel().writeAndFlush(Unpooled.wrappedBuffer("bbbb$_".getBytes()));
        cf.channel().writeAndFlush(Unpooled.wrappedBuffer("cccc$_".getBytes()));


        //等待客户端端口关闭
        cf.channel().closeFuture().sync();
        group.shutdownGracefully();

    }
}

ClientHandler.java

import io.netty.channel.ChannelHandlerAdapter;
import io.netty.channel.ChannelHandlerContext;
import io.netty.util.ReferenceCountUtil;

public class ClientHandler extends ChannelHandlerAdapter{

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        System.out.println("client channel active... ");
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        try {
            String response = (String)msg;
            System.out.println("Client: " + response);
        } finally {
            ReferenceCountUtil.release(msg);
        }
    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        ctx.close();
    }

}

Server.java


import java.nio.ByteBuffer;

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.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;
import io.netty.handler.codec.DelimiterBasedFrameDecoder;
import io.netty.handler.codec.FixedLengthFrameDecoder;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;

public class Server {

    public static void main(String[] args) throws Exception{
        //1 创建2个线程,一个是负责接收客户端的连接。一个是负责进行数据传输的
        EventLoopGroup pGroup = new NioEventLoopGroup();
        EventLoopGroup cGroup = new NioEventLoopGroup();

        //2 创建服务器辅助类
        ServerBootstrap b = new ServerBootstrap();
        b.group(pGroup, cGroup)
         .channel(NioServerSocketChannel.class)
         .option(ChannelOption.SO_BACKLOG, 1024)
         .option(ChannelOption.SO_SNDBUF, 32*1024)
         .option(ChannelOption.SO_RCVBUF, 32*1024)
         .childHandler(new ChannelInitializer<SocketChannel>() {
            @Override
            protected void initChannel(SocketChannel sc) throws Exception {
                //设置特殊分隔符
                ByteBuf buf = Unpooled.copiedBuffer("$_".getBytes());
                sc.pipeline().addLast(new DelimiterBasedFrameDecoder(1024, buf));
                //设置字符串形式的解码
                sc.pipeline().addLast(new StringDecoder());
                sc.pipeline().addLast(new ServerHandler());
            }
        });

        //4 绑定连接
        ChannelFuture cf = b.bind(8765).sync();

        //等待服务器监听端口关闭
        cf.channel().closeFuture().sync();
        pGroup.shutdownGracefully();
        cGroup.shutdownGracefully();

    }

}
ServerHandler.java
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerAdapter;
import io.netty.channel.ChannelHandlerContext;

public class ServerHandler extends ChannelHandlerAdapter {


    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        System.out.println(" server channel active... ");
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        String request = (String)msg;
        System.out.println("Server :" + msg);
        String response = "服务器响应:" + msg + "$_";
        ctx.writeAndFlush(Unpooled.copiedBuffer(response.getBytes()));
    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {

    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable t) throws Exception {
        ctx.close();
    }




}
版权声明:本文为自由の力原创文章,未经允许不得转载。

netty 数据分包、组包、粘包处理机制

转载自 断鸿零雁 blog.163.com/linfenliang@126 1.            frame包整体功能描述 此包主要作用于对TCP/IP数据包的分包和包重组,常用于数据的流传...
  • cluzax
  • cluzax
  • 2015年07月09日 07:02
  • 2372

Netty (四) 分隔符和定长解码器的使用

TCP以流的形式进行数据传输,上层的应用协议为了对消息进行划分,往往采用如下的4种方式。 (1)消息长度固定,累计读到长度总和为定长len的报文后,就认为读取到了一个完整的消息;然后重新开始读取下一...
  • LANGZI7758521
  • LANGZI7758521
  • 2016年09月30日 16:24
  • 3297

Netty 缓存buffer介绍及使用

每当你需要传输数据时,它必须包含一个缓冲区。Java NIO API 自带的缓冲区类是相当有限的,没有经过优化,使用 JDK 的 ByteBuffer 操作更复杂。缓冲区是一个重要的组建,它是 API...
  • cuiyaoqiang
  • cuiyaoqiang
  • 2016年06月13日 10:19
  • 8170

04 Transports(传输)

本章内容 Transports(传输) NIO(non-blocking IO,New IO), OIO(Old IO,blocking IO), Local(本地), Embedded(嵌入式...
  • codemosi
  • codemosi
  • 2015年11月17日 14:26
  • 274

Netty之解决TCP粘包拆包(自定义协议)

1、什么是粘包/拆包        一般所谓的TCP粘包是在一次接收数据不能完全地体现一个完整的消息数据。TCP通讯为何存在粘包呢?主要原因是TCP是以流的方式来处理数据,再加上网络上MTU的往往小...
  • zbw18297786698
  • zbw18297786698
  • 2016年12月16日 13:35
  • 7081

你真的会用Gson吗?Gson使用指南(一)

本文链接:http://www.jianshu.com/p/e740196225a4 JSON (官网) 是一种文本形式的数据交换格式,它比XML更轻量、比二进制容易阅读和编写,调式也更...
  • wdd1324
  • wdd1324
  • 2017年06月02日 14:26
  • 157

Netty解决粘包问题(1) 自定义分隔符

见如下代码Client.javaimport io.netty.bootstrap.Bootstrap; import io.netty.buffer.ByteBuf; import io.netty...
  • taoli1986
  • taoli1986
  • 2016年08月30日 21:37
  • 621

netty处理粘包问题——2

TCP网络通信时候会发生粘包/拆包的问题,接下来探讨其解决之道。 什么是粘包/拆包 一般所谓的TCP粘包是在一次接收数据不能完全地体现一个完整的消息数据。TCP通讯为何存在粘包呢?主要...
  • bestone0213
  • bestone0213
  • 2015年07月28日 17:38
  • 668

netty拆包/粘包的解决方案

netty拆包/粘包的解决方案刚开始学拆包/粘包的时候确实不太好理解,我反复看了几遍就理解了。写下了加深记忆,也希望对大家有所帮助。在文章开头免费为大家送上代码以便大家对照着学习。本章只介绍简单的二个...
  • mffandxx
  • mffandxx
  • 2016年07月16日 12:01
  • 3592

android之HTTP请求后台数据,GSON解析数据,异步获取数据

android之HTTP请求后台数据   /* * 查询从URL得到的字符串 */ public static String queryStringForGet(String url)...
  • u012482178
  • u012482178
  • 2015年02月02日 15:36
  • 1128
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Netty解决粘包问题(1) 自定义分隔符
举报原因:
原因补充:

(最多只允许输入30个字)