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);
        }
    }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM