Netty的基础了解可以先参考以下链接

1、搭建服务器

搭建服务器需要什么?

搭建一个 Netty Server需要两个类,一个是启动类,另一个是业务处理类。

先新建一个maven项目,在pom文件里添加 netty 的依赖包,版本为5.0.0

java 使用netty创建TCP客户端连接并调用客户端发送数据 netty客户端编写_客户端

<dependencies>
        <dependency>
            <groupId>io.netty</groupId>
            <artifactId>netty-all</artifactId>
            <version>5.0.0.Alpha1</version>
        </dependency>
</dependencies>

 

一、启动类:

public class EchoServer {
    private final int port;
    public EchoServer(int port)
    {
        this.port=port;
    }

    public void start() throws Exception
    {
        EventLoopGroup group=new NioEventLoopGroup();
        try
        {
            //create ServerBootstrap instance
            ServerBootstrap b=new ServerBootstrap();
            //Specifies NIO transport,local socket address
            //Adds handler to channel pipeline
            b.group(group).channel(NioServerSocketChannel.class).localAddress(port)  // 这里告诉Channel如何接收新的连接
                .childHandler(new ChannelInitializer<Channel>() {
                    @Override
                    protected void initChannel(Channel ch) throws Exception
                    {
                        // 自定义处理类
                        ch.pipeline().addLast(new EchoServerHandler());
                    }
                })
            .option(ChannelOption.SO_BACKLOG, 128)
            .childOption(ChannelOption.SO_KEEPALIVE, true);
            // 绑定端口,开始接收进来的连接
            ChannelFuture f = b.bind(port).sync();
            System.out.println(EchoServer.class.getName()+" started and listen on "+f.channel().localAddress());
            // 等待服务器socket关闭
            f.channel().closeFuture().sync();
        }catch (Exception e){
            System.out.println(e);
        }
        finally {
            group.shutdownGracefully().sync();
        }
    }

       public static void main(String[] agrs)throws Exception
    {
        System.out.println("Server_star");
        new EchoServer(8001).start();
        System.out.println("Server_end");
    }

}

二、业务处理类:

public class EchoServerHandler extends ChannelInboundHandlerAdapter {
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception
    {
        System.out.println("客户端连上...");
    }
    @Override
    public void channelRead(ChannelHandlerContext ctx,Object msg) throws Exception
    {
        try {
                ByteBuf in = (ByteBuf) msg;
                System.out.println( new Date().toString()  );
                System.out.println("收到的:"+in.toString(CharsetUtil.UTF_8));
                ctx.write(Unpooled.copiedBuffer("你好, I am server!", CharsetUtil.UTF_8));
                ctx.flush();
        }catch (Exception e){
            System.out.println("异常"+e);
        }finally {
           ReferenceCountUtil.release(msg);
        }
    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception
    {
        try {
            ctx.flush();
        }catch (Exception e){
            System.out.println("异常"+e);
        }
    }


    @Override
    public void exceptionCaught(ChannelHandlerContext ctx,Throwable cause) throws Exception
    {
        System.out.println("exceptionCaught:"+ctx);
        cause.printStackTrace();
        ctx.close();
    }

}

 

三、测试搭建是否成功

我们可以去自定义客户端程序,这里为了方便使用 telnet 充当客户端。需要注意的是,Windows 默认是没有开启 telnet 客户端的,需要我们手动开启。菜单->控制面板->程序->打开或关闭Windows功能,设置如图:

java 使用netty创建TCP客户端连接并调用客户端发送数据 netty客户端编写_Netty_02

设置完成后,启动运行服务端的程序EchoServer,在 cmd 窗口输入命令如下: telnet + ip + 端口号 

java 使用netty创建TCP客户端连接并调用客户端发送数据 netty客户端编写_客户端_03

进入如下界面 ,即连接成功

 

java 使用netty创建TCP客户端连接并调用客户端发送数据 netty客户端编写_客户端_04

同时控制台输出连接情况

java 使用netty创建TCP客户端连接并调用客户端发送数据 netty客户端编写_Netty_05

接下来,输入一个字符,比如'a' ,telnet实时发送该字符给服务端(如果telnet 窗口看不到输入的字符,只要输入 ctrl+L 就可以看到输入的字符了)。控制台打印收到的客户端数据,并发送一条应答信息:Hello,I am client!

java 使用netty创建TCP客户端连接并调用客户端发送数据 netty客户端编写_System_06

telnet客户端:收到来自服务端的数据

java 使用netty创建TCP客户端连接并调用客户端发送数据 netty客户端编写_Netty_07

 上述测试方法,每输入一个字符都会当成一次通讯过程。如果想从客户端发送一段完整的数据,可以在客户端输入 Ctrl+]

java 使用netty创建TCP客户端连接并调用客户端发送数据 netty客户端编写_System_08

使用telnet 的send命令发送数据,如下图。这样就可以发送一整段信息。

java 使用netty创建TCP客户端连接并调用客户端发送数据 netty客户端编写_System_09

 服务端收到的数据:

java 使用netty创建TCP客户端连接并调用客户端发送数据 netty客户端编写_客户端_10

 以上步骤跑通后,说明服务端已搭建成功。

2、搭建客户端

搭建一个 Netty Client 同样也需要两个类,一个是启动类,另一个是业务处理类。

一、启动类

public class EchoClient {
    private final String host;
    private final int port;
    public EchoClient(String host,int port)
    {
        this.host=host;
        this.port=port;
    }

    public void start() throws Exception
    {
        EventLoopGroup group =new NioEventLoopGroup();
        try{
            Bootstrap b=new Bootstrap();
            b.group(group).channel(NioSocketChannel.class).remoteAddress(new InetSocketAddress(host,port))
                    .handler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel ch) throws Exception
                        {
                            ch.pipeline().addLast(new EchoClientHandler());
                        }
                    });
            Channel channel  = b.connect().sync().channel();
            channel.closeFuture().sync();


        }finally {
            group.shutdownGracefully().sync();
        }
    }

    public static void main(String[] agrs) throws Exception
    {
        System.out.println("client_star");
        new EchoClient("localhost",8001).start();
    }


}

二、业务处理类

public class EchoClientHandler extends SimpleChannelInboundHandler<ByteBuf> {
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception
    {
        System.out.println("服务端连上了");
        ctx.write(Unpooled.copiedBuffer("Hello, I am client!", Charset.forName("UTF-8")));
        ctx.flush();

    }

    @Override
    public void messageReceived(ChannelHandlerContext ctx,ByteBuf msg)throws Exception{
        try {
             System.out.println( new Date().toString()  );     
             System.out.println("Client Received!: "+ msg.toString(CharsetUtil.UTF_8));  
        }catch (Exception e){
            System.out.println("异常"+e);
        }
    }

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


}

 

3、服务端与客户端通信

一、启动运行服务端的程序EchoServer

java 使用netty创建TCP客户端连接并调用客户端发送数据 netty客户端编写_System_11

二、启动运行客户端的程序EchoClient

java 使用netty创建TCP客户端连接并调用客户端发送数据 netty客户端编写_客户端_12