`
Donald_Draper
  • 浏览: 981223 次
社区版块
存档分类
最新评论

netty 网络通信示例一

阅读更多
Netty系列之Netty高性能之道:http://www.infoq.com/cn/articles/netty-high-performance
Nio通讯框架学习:http://guojuanjun.blog.51cto.com/277646/841342/
Netty是什么:http://lippeng.iteye.com/blog/1907279
Java NIO框架Netty教程:http://blog.csdn.net/kobejayandy/article/details/11495509
netty初步,与各个版本的比较 :http://blog.csdn.net/u010154380/article/details/46988269
Netty版本升级血泪史之线程篇:http://www.infoq.com/cn/articles/netty-version-upgrade-history-thread-part/
     Netty是由JBOSS提供的一个java开源框架。Netty提供异步的、事件驱动的网络应用程序框架和工具,用以快速开发高性能、高可靠性的网络服务器和客户端程序。具体的我们就不在详讲,参看上面的引用连接。
     从今天起,我们从netty的几个实例来看,如何构建网络通信,本文中的所用的netty版本为4.1.12,相关的源码github地址为https://github.com/Donaldhan/netty_demo
实例1,简单的消息通信应用:
服务端:
package netty.main.echo;

import java.net.InetSocketAddress;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.ChannelPipeline;
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.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
import io.netty.handler.ssl.SslContext;
import io.netty.handler.ssl.SslContextBuilder;
import io.netty.handler.ssl.util.SelfSignedCertificate;
import netty.handler.echo.EchoServerHandler;

/**
 * Discards any incoming data.
 * @author donald
 * 2017年6月16日
 * 上午9:39:53
 */
public class EchoServer {
	private static final Logger log = LoggerFactory.getLogger(EchoServer.class);
	 static final boolean SSL = System.getProperty("ssl") != null;
	private static final  String ip = "192.168.31.153";
	private static final  int port = 10010;
    public static void main(String[] args) throws Exception {
      run();
    }
    public static void run() throws Exception {
    	 // Configure SSL.
        final SslContext sslCtx;
        if (SSL) {
            SelfSignedCertificate ssc = new SelfSignedCertificate();
            sslCtx = SslContextBuilder.forServer(ssc.certificate(), ssc.privateKey()).build();
        } else {
            sslCtx = null;
        }

    	/*
    	 * EventLoopGroup(多线程事件loop),处理IO操作,这里我们用了两个事件loop
    	 * 第一个用于处理器监听连接请求,第二个用于数据的传输;
    	 * 具体线程是多少依赖于事件loop的具体实现
    	 * */
        EventLoopGroup bossGroup = new NioEventLoopGroup(); // (1)
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        try {
        	//ServerBootstrap,用于配置服务端,一般为ServerSocket通道
            ServerBootstrap serverBoot = new ServerBootstrap(); 
            serverBoot.group(bossGroup, workerGroup)
             .channel(NioServerSocketChannel.class) 
             .childHandler(new ChannelInitializer<SocketChannel>() { 
                 @Override
                 public void initChannel(SocketChannel ch) throws Exception {
                	//添加通道处理器到通道关联的管道,准确的中文翻译为管道线, 此管道线与Mina中过滤链十分相似,
                	//ChannelInitializer用于配置通道的管道线,ChannelPipeline
                	 ChannelPipeline pipeline = ch.pipeline();
                     if (sslCtx != null) {
                    	 pipeline.addLast(sslCtx.newHandler(ch.alloc()));
                     }
                     pipeline.addLast(new LoggingHandler(LogLevel.INFO));
                     pipeline.addLast(new EchoServerHandler());
                 }
             })
             .option(ChannelOption.SO_BACKLOG, 128)//socket监听器连接队列大小、
             .childOption(ChannelOption.SO_KEEPALIVE, true); //保活,此配置针对ServerSocket通道接收连接产生的Socket通道
            InetSocketAddress inetSocketAddress = new InetSocketAddress(ip,port);
            // 绑定地址,开始监听
            ChannelFuture f = serverBoot.bind(inetSocketAddress).sync();
            log.info("=========Server is start=========");
            //等待,直到ServerSocket关闭
            f.channel().closeFuture().sync();
        } finally {
            workerGroup.shutdownGracefully();
            bossGroup.shutdownGracefully();
        }
    }
}

服务端处理器:
package netty.handler.echo;

import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.util.CharsetUtil;
import io.netty.util.ReferenceCountUtil;

/**
 * Handles a server-side channel.
 * @author donald
 * 2017年6月16日
 * 上午9:36:53
 */
public class EchoServerHandler extends ChannelInboundHandlerAdapter {
   private static final Logger log = LoggerFactory.getLogger(EchoServerHandler.class);
   /**
    * 读client通道数据,通道处理器上下文ChannelHandlerContext与Mina的会话很像
    */
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) {
    	ByteBuf in = (ByteBuf)msg;
    	byte[] bytes = new byte[in.writerIndex()];
    	in.readBytes(bytes);
    	//针对堆buf,direct buf不支持
//    	byte[] bytes = in.array();
    	String message = null;
		try {
			message = new String(bytes,"UTF-8");
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
    	try{
    		log.info("===Server reciever message:" +message);
    	}
    	finally{
    		//如果msg为引用计数对象,在使用后注意释放,一般在通道handler中释放
//            ReferenceCountUtil.release(msg);
    	}
    	String ackMessage = "hello client ...";
    	in.clear();
    	try {
			in.writeBytes(ackMessage.getBytes("UTF-8"));
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
    	ctx.write(in);
        
    }
    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) {
        ctx.flush();
    }
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
    	//异常发生时,关闭连接
        cause.printStackTrace();
        ctx.close();
    }
}

客户端:
package netty.main.echo;

import java.net.InetSocketAddress;

import javax.net.ssl.SSLException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
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.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
import io.netty.handler.ssl.SslContext;
import io.netty.handler.ssl.SslContextBuilder;
import io.netty.handler.ssl.util.InsecureTrustManagerFactory;
import netty.handler.echo.EchoClientHandler;
/**
 * 
 * @author donald
 * 2017年6月20日
 * 下午12:44:58
 */
public final class EchoClient {
	private static final Logger log = LoggerFactory.getLogger(EchoClient.class);
	private static final boolean SSL = System.getProperty("ssl") != null;
	private static final String ip = System.getProperty("host", "192.168.31.153");
	private static final int port = Integer.parseInt(System.getProperty("port", "10010"));
    public static void main(String[] args) throws Exception {
       run();
    }
    private static void run() throws SSLException, InterruptedException{
    	 //配置安全套接字上下文
        final SslContext sslCtx;
        if (SSL) {
            sslCtx = SslContextBuilder.forClient()
                .trustManager(InsecureTrustManagerFactory.INSTANCE).build();
        } else {
            sslCtx = null;
        }
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        try {
        	//Bootstrap,用于配置客户端,一般为Socket通道
            Bootstrap bootstrap = new Bootstrap();
            bootstrap.group(workerGroup)
             .channel(NioSocketChannel.class)
             .handler(new ChannelInitializer<SocketChannel>() {
                 @Override
                 protected void initChannel(SocketChannel ch) throws Exception {
                	 //添加安全套接字处理器和通道处理器到
                     ChannelPipeline pipeline = ch.pipeline();
                     if (sslCtx != null) {
                    	 pipeline.addLast(sslCtx.newHandler(ch.alloc(), ip, port));
                     }
                     pipeline.addLast(new LoggingHandler(LogLevel.INFO));
                     pipeline.addLast(new EchoClientHandler());
                 }
             });
            InetSocketAddress inetSocketAddress = new InetSocketAddress(ip,port);
            //连接socket地址
            ChannelFuture f = bootstrap.connect(inetSocketAddress).sync();
            log.info("=========Client is start=========");
            //等待,直到连接关闭
            f.channel().closeFuture().sync();
        } finally {
        	workerGroup.shutdownGracefully();
        }
    }
}

客户端处理器:
package netty.handler.echo;


import java.io.UnsupportedEncodingException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;

/**
 * 
 * @author donald
 * 2017年6月20日
 * 下午12:45:04
 */
public class EchoClientHandler extends ChannelInboundHandlerAdapter {
	private static final Logger log = LoggerFactory.getLogger(EchoClientHandler.class);
	private final ByteBuf firstMessage;
	public EchoClientHandler() {
		String message = "Hello Server...";
        firstMessage = Unpooled.buffer(1024);//堆buffer
        try {
			firstMessage.writeBytes(message.getBytes("UTF-8"));
			firstMessage.retainedDuplicate();
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
        
    }
    @Override
    public void channelActive(ChannelHandlerContext ctx) {
        ctx.write(firstMessage);
        ctx.flush();
    }  
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
    	ByteBuf in = (ByteBuf)msg;
    	byte[] bytes = new byte[in.writerIndex()];
    	in.readBytes(bytes);
    	//针对堆buf,direct buf不支持
//    	byte[] bytes = in.array();
    	String message = new String(bytes,"UTF-8");
    	log.info("===Client reciever ack message from Server:" +message);
    }
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        cause.printStackTrace();
        ctx.close();
    }
}

分别启动服务端与客户端,控制台输出:
服务端:
[INFO ] 2017-07-05 21:23:51 netty.main.echo.EchoServer =========Server is start=========
[INFO ] 2017-07-05 21:23:59 io.netty.handler.logging.LoggingHandler [id: 0xa4c1b700, L:/192.168.31.153:10010 - R:/192.168.31.153:28426] REGISTERED
[INFO ] 2017-07-05 21:23:59 io.netty.handler.logging.LoggingHandler [id: 0xa4c1b700, L:/192.168.31.153:10010 - R:/192.168.31.153:28426] ACTIVE
[INFO ] 2017-07-05 21:23:59 io.netty.handler.logging.LoggingHandler [id: 0xa4c1b700, L:/192.168.31.153:10010 - R:/192.168.31.153:28426] READ: 15B
         +-------------------------------------------------+
         |  0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f |
+--------+-------------------------------------------------+----------------+
|00000000| 48 65 6c 6c 6f 20 53 65 72 76 65 72 2e 2e 2e    |Hello Server... |
+--------+-------------------------------------------------+----------------+
[INFO ] 2017-07-05 21:23:59 netty.handler.echo.EchoServerHandler ===Server reciever message:Hello Server...
[INFO ] 2017-07-05 21:23:59 io.netty.handler.logging.LoggingHandler [id: 0xa4c1b700, L:/192.168.31.153:10010 - R:/192.168.31.153:28426] WRITE: 16B
         +-------------------------------------------------+
         |  0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f |
+--------+-------------------------------------------------+----------------+
|00000000| 68 65 6c 6c 6f 20 63 6c 69 65 6e 74 20 2e 2e 2e |hello client ...|
+--------+-------------------------------------------------+----------------+
[INFO ] 2017-07-05 21:23:59 io.netty.handler.logging.LoggingHandler [id: 0xa4c1b700, L:/192.168.31.153:10010 - R:/192.168.31.153:28426] READ COMPLETE
[INFO ] 2017-07-05 21:23:59 io.netty.handler.logging.LoggingHandler [id: 0xa4c1b700, L:/192.168.31.153:10010 - R:/192.168.31.153:28426] FLUSH

客户端:
[INFO ] 2017-07-05 21:23:59 io.netty.handler.logging.LoggingHandler [id: 0xbd3abb79] REGISTERED
[INFO ] 2017-07-05 21:23:59 io.netty.handler.logging.LoggingHandler [id: 0xbd3abb79] CONNECT: /192.168.31.153:10010
[INFO ] 2017-07-05 21:23:59 netty.main.echo.EchoClient =========Client is start=========
[INFO ] 2017-07-05 21:23:59 io.netty.handler.logging.LoggingHandler [id: 0xbd3abb79, L:/192.168.31.153:28426 - R:/192.168.31.153:10010] ACTIVE
[INFO ] 2017-07-05 21:23:59 io.netty.handler.logging.LoggingHandler [id: 0xbd3abb79, L:/192.168.31.153:28426 - R:/192.168.31.153:10010] WRITE: 15B
         +-------------------------------------------------+
         |  0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f |
+--------+-------------------------------------------------+----------------+
|00000000| 48 65 6c 6c 6f 20 53 65 72 76 65 72 2e 2e 2e    |Hello Server... |
+--------+-------------------------------------------------+----------------+
[INFO ] 2017-07-05 21:23:59 io.netty.handler.logging.LoggingHandler [id: 0xbd3abb79, L:/192.168.31.153:28426 - R:/192.168.31.153:10010] FLUSH
[INFO ] 2017-07-05 21:23:59 io.netty.handler.logging.LoggingHandler [id: 0xbd3abb79, L:/192.168.31.153:28426 - R:/192.168.31.153:10010] READ: 16B
         +-------------------------------------------------+
         |  0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f |
+--------+-------------------------------------------------+----------------+
|00000000| 68 65 6c 6c 6f 20 63 6c 69 65 6e 74 20 2e 2e 2e |hello client ...|
+--------+-------------------------------------------------+----------------+
[INFO ] 2017-07-05 21:23:59 netty.handler.echo.EchoClientHandler ===Client reciever ack message from Server:hello client ...
[INFO ] 2017-07-05 21:23:59 io.netty.handler.logging.LoggingHandler [id: 0xbd3abb79, L:/192.168.31.153:28426 - R:/192.168.31.153:10010] READ COMPLETE
0
2
分享到:
评论

相关推荐

    netty通信完整示例

    Netty 是一个高性能、异步事件驱动的网络应用程序框架,用于快速开发可维护的高性能协议服务器和客户端。这个“netty通信完整示例”提供了一套完整的Netty使用案例,包括了jar包、服务器端、客户端、编码器和解码器...

    基于Netty框架的网络通信示例.zip

    本项目是一个基于Netty框架的网络通信示例,涵盖了多种网络通信场景,包括TCP、UDP、WebSocket等。项目展示了如何使用Netty进行高性能的异步网络编程,并提供了丰富的示例代码和测试用例。 适用人群 有一定Java...

    Netty初始学习示例

    在网络通信中,由于数据包大小不固定,可能会出现粘包或拆包现象。Netty通过自定义的解码器如`LengthFieldBasedFrameDecoder`来解决这个问题,它根据长度字段来分割数据包。 7. **心跳机制**: 为了检测网络连接...

    Android基于Netty框架实现通信

    在Android开发中,为了实现高效的网络通信,开发者常常会选择使用Netty框架。Netty是一个高性能、异步事件驱动的网络应用程序框架,适用于多种协议的服务器和客户端应用。本篇文章将详细探讨如何在Android环境中利用...

    netty 入门Reactor示例

    Netty 是一个高性能、异步事件驱动的网络应用程序框架,用于快速开发可维护的高性能协议服务器和客户端。在深入理解Netty的Reactor模式之前,我们先了解一下什么是Reactor模式。 Reactor模式是一种事件处理模式,它...

    基于netty的即时通信

    在即时通信领域,Netty作为一个高性能、异步事件驱动的网络应用框架,广泛应用于各种复杂的通信系统。本项目“基于Netty的即时通信”旨在演示如何利用Netty构建一个简单的聊天应用,它包括服务端和客户端,实现了多...

    netty框架,服务端、客户端代码示例

    在这个"Netty框架,服务端、客户端代码示例"中,我们将深入探讨如何使用Netty构建服务端和客户端的通信。 首先,让我们了解Netty的基本架构。Netty的核心是它的“线程模型”和“通道”概念。线程模型采用“事件循环...

    Netty实现简单的客户端服务端通信示例

    总的来说,Netty 的简单客户端-服务端通信示例帮助我们理解了 Netty 的基本架构和工作原理。通过实践这个示例,你可以进一步探索 Netty 如何处理网络连接、数据传输以及自定义处理器的实现,从而更好地掌握 Netty 在...

    Android-netty和socket通信的demo

    在Android开发中,网络通信是不可或缺的一部分,而Netty是一个高效、强大的网络应用程序框架,它为构建高性能、稳定的网络服务器提供了便利。本示例“Android-netty和socket通信的demo”将展示如何在Android平台上...

    基于Netty框架的网络通信项目.zip

    本项目是一个基于Netty框架的网络通信项目,涵盖了多种网络通信场景和功能实现。Netty是一个高性能、异步事件驱动的网络应用框架,广泛用于构建高性能的网络服务器和客户端。本项目通过多个示例代码,展示了如何使用...

    android netty cli +probuf示例

    总结来说,“android netty cli +protobuf示例”展示了如何在Android客户端利用Netty的异步网络通信能力和Protobuf的数据序列化特性,构建一个高效的即时通讯系统。这个示例涵盖了从消息定义到网络通信的全过程,...

    (源码)基于Netty框架的网络通信系统.zip

    本项目是一个基于Netty框架的网络通信系统,涵盖了多种网络通信场景和协议,包括TCP、UDP、HTTP、WebSocket等。通过使用Netty的高性能异步事件驱动框架,实现了高效、可靠的网络通信。项目中包含了多种网络编程的...

    Netty通信服务器搭建demo

    Netty是一款高性能、异步事件驱动的网络应用框架,它为Java开发人员提供了构建高性能、稳定、可扩展的网络服务器和客户端的API。在“Netty通信服务器搭建demo”中,我们将探讨如何利用Netty来搭建一个简单的通信...

    Android使用Netty网络框架实践(客户端、服务端)

    在Android开发中,有时我们需要构建高性能的网络通信应用,这时Netty框架就能派上大用场。Netty是一个异步事件驱动的网络应用程序框架,它为高性能、高可用性的网络服务器和客户端提供了一种简单易用的方式。本实践...

    netty通讯示例

    Netty 是一个高性能、异步事件驱动的网络应用程序框架,...通过深入理解并实践这个“netty通讯示例”,你可以掌握Netty的基本用法,以及如何处理网络通信中的常见问题,这对于构建高并发、高性能的网络应用至关重要。

    netty5.0通信jar和客户端服务器demo

    总结来说,Netty 5.0提供了一套强大且灵活的网络通信框架,通过异步I/O、高效的内存管理以及灵活的Pipeline设计,极大地简化了高性能网络应用的开发。通过"netty_11-07_ok"这样的示例,开发者可以深入理解Netty的...

    java nio&netty系列之三netty网络模型代码以及简化版代码示例

    本篇将主要探讨Netty网络模型的代码实现及简化版代码示例。 首先,Netty的核心是它的事件驱动模型,也称为Reactor模式。在Netty中,BossGroup负责接收新的连接请求,WorkerGroup则处理已连接的SocketChannel上的...

    java netty通信

    通过上述知识点的学习和实践,你可以构建出稳定、高效的网络通信服务。在实际项目中,结合具体的业务需求,灵活运用Netty提供的各种组件和设计模式,能够大大提高开发效率和系统的可靠性。在压缩包文件`test`中,...

    netty官方例子

    Netty 是一个高性能、异步事件驱动的网络应用程序框架,用于快速开发可维护的高性能协议服务器和客户端。这个“netty官方例子”压缩包提供了一系列的示例代码,帮助开发者更好地理解和运用Netty框架。这些例子是基于...

    NettyDemo包含客户端服务端

    综上所述,"NettyDemo" 示例提供了 Netty 在 Android 和 SpringBoot 环境下的实际应用案例,帮助开发者理解如何在不同平台上构建高效、可靠的网络通信系统。通过研究这个示例,可以深入学习 Netty 的核心概念以及...

Global site tag (gtag.js) - Google Analytics