Netty——简单创建服务器、客户端通讯

       Netty 是一个基于NIO的客户、服务器端编程框架,使用Netty 可以确保你快速和简单的开发出一个网络应用,例如实现了某种协议的客户,服务端应用。Netty相当简化和流线化了网络应用的编程开发过程,例如,TCP和UDP的socket服务开发。

  Netty简单来说就是socket通讯,支持多协议的通讯

 对 创建 netty 的过程作了详细的解析

1、简单创建一个Netty服务器

package com.netty.test;

import java.net.InetAddress;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
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.Delimiters;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;

/**
 * Netty4 服务端代码
 *
 */
public class HelloWorldServer {

    
    public static void main(String[] args) {
        // EventLoop 代替原来的 ChannelFactory
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        
        try {
ServerBootstrap serverBootstrap
= new ServerBootstrap();        //创建 一个netty 服务器 // server端采用简洁的连写方式,client端才用分段普通写法。 serverBootstrap.group(bossGroup, workerGroup) .channel(NioServerSocketChannel.class)              // 指定channel[通道]类型 .childHandler(new ChannelInitializer<SocketChannel>() {    // 指定Handler [操纵者]
@Override
public void initChannel(SocketChannel ch) throws Exception { // 以("\n")为结尾分割的 解码器 ch.pipeline().addLast("framer", new DelimiterBasedFrameDecoder(8192, Delimiters.lineDelimiter())); // 字符串 解码 和 编码 默认的 StringDecoder 字符串形式输出 ch.pipeline().addLast("decoder", new StringDecoder()); ch.pipeline().addLast("encoder", new StringEncoder()); ch.pipeline().addLast(new HelloServerHandler());     // 添加自己的对 上传数据的处理 }
}).option(ChannelOption.SO_KEEPALIVE,
true);
       ChannelFuture f
= serverBootstrap.bind(8000).sync();           // 绑定 8000 端口 f.channel().closeFuture().sync(); } catch (InterruptedException e) { } finally { workerGroup.shutdownGracefully(); // 销毁 netty bossGroup.shutdownGracefully(); } } /** * 自己对 处理数据 * * @author flm * 2017年11月10日 */ private static class HelloServerHandler extends ChannelInboundHandlerAdapter { @Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { // 收到消息直接打印输出 System.out.println(ctx.channel().remoteAddress() + " Say : " + msg); // 返回客户端消息 - 我已经接收到了你的消息 ctx.writeAndFlush("server Received your message !\n"); } /* * * 覆盖 channelActive 方法 在channel被启用的时候触发 (在建立连接的时候) * * channelActive 和 channelInActive 在后面的内容中讲述,这里先不做详细的描述 */ @Override public void channelActive(ChannelHandlerContext ctx) throws Exception { System.out.println("RamoteAddress : " + ctx.channel().remoteAddress() + " active !"); ctx.writeAndFlush("Welcome to " + InetAddress.getLocalHost().getHostName() + " service!\n"); //回复 super.channelActive(ctx); } }

 

 

2、netty 客户端 创建

package com.netty.test;

import java.net.InetSocketAddress;
import java.util.Date;

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.DelimiterBasedFrameDecoder;
import io.netty.handler.codec.Delimiters;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;

/**
 * Netty4 客户端代码
 * 
 */
public class HelloWorldClient {

    public static void main(String args[]) {

        // Bootstrap,且构造函数变化很大,这里用无参构造。
        Bootstrap bootstrap = new Bootstrap();
        // 指定channel[通道]类型
        bootstrap.channel(NioSocketChannel.class);
        // 指定Handler [操纵者]
        bootstrap.handler(new ChannelInitializer<Channel>() {

            @Override
            protected void initChannel(Channel ch) throws Exception {
                ChannelPipeline pipeline = ch.pipeline();
                
                /*
                 * 这个地方的 必须和服务端对应上。否则无法正常解码和编码
                 * 
                 */
                pipeline.addLast("framer", new DelimiterBasedFrameDecoder(8192, Delimiters.lineDelimiter()));
                pipeline.addLast("decoder", new StringDecoder());
                pipeline.addLast("encoder", new StringEncoder());

                // 客户端的逻辑,自己对数据处理
                pipeline.addLast(new HelloClientHandler());  
            }
        });
        // 指定EventLoopGroup [事件 组]
        bootstrap.group(new NioEventLoopGroup());

        // 连接到本地的8000端口的服务端
        bootstrap.connect(new InetSocketAddress("127.0.0.1", 8000));

    }




    /**
     * 客户端的逻辑,自己对数据处理
     * 
     * @author flm
     * 2017年11月10日
     */
    private static class HelloClientHandler extends ChannelInboundHandlerAdapter {
        
        /*
         * 监听 服务器 发送来的数据
         */
        @Override
        public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {

            System.out.println("Server say : " + msg.toString());

        }

        /*
         * 启动客户端 时触发
         */
        @Override
        public void channelActive(ChannelHandlerContext ctx) throws Exception {
            System.out.println("Client active ");
            ctx.writeAndFlush("我是 client " + new Date() + "\n");
            super.channelActive(ctx);
        }

        /*
         * 关闭 客户端 触发
         */
        @Override
        public void channelInactive(ChannelHandlerContext ctx) throws Exception {
            System.out.println("Client close ");
            super.channelInactive(ctx);
        }
    }
}

 

posted @ 2017-11-10 10:58  低调人生  阅读(2046)  评论(0编辑  收藏  举报