关闭

Java NIO框架Netty简单使用

6719人阅读 评论(4) 收藏 举报
分类:

转载请注明出处:http://blog.csdn.net/anxpp/article/details/52108238,谢谢!

    之前写了一篇文章:Java 网络IO编程总结(BIO、NIO、AIO均含完整实例代码),介绍了如何使用Java原生IO支持进行网络编程,本文介绍一种更为简单的方式,即Java NIO框架。

    Netty是业界最流行的NIO框架之一,具有良好的健壮性、功能、性能、可定制性和可扩展性。同时,它提供的十分简单的API,大大简化了我们的网络编程。

    同Java IO介绍的文章一样,本文所展示的例子,实现了一个相同的功能。

1、服务端

    Server:

package com.anxpp.io.calculator.netty;
import io.netty.bootstrap.ServerBootstrap;
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;
public class Server {
    private int port;
    public Server(int port) {
        this.port = port;
    }
    public void run() throws Exception {
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        try {
            ServerBootstrap b = new ServerBootstrap();
            b.group(bossGroup, workerGroup)
             .channel(NioServerSocketChannel.class)
             .option(ChannelOption.SO_BACKLOG, 1024)
             .childOption(ChannelOption.SO_KEEPALIVE, true)
             .childHandler(new ChannelInitializer<SocketChannel>() {
                 @Override
                 public void initChannel(SocketChannel ch) throws Exception {
                     ch.pipeline().addLast(new ServerHandler());
                 }
             });
            ChannelFuture f = b.bind(port).sync();
            System.out.println("服务器开启:"+port);
            f.channel().closeFuture().sync();
        } finally {
            workerGroup.shutdownGracefully();
            bossGroup.shutdownGracefully();
        }
    }
    public static void main(String[] args) throws Exception {
        int port;
        if (args.length > 0) {
            port = Integer.parseInt(args[0]);
        } else {
            port = 9090;
        }
        new Server(port).run();
    }
}

    ServerHandler:

package com.anxpp.io.calculator.netty;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import java.io.UnsupportedEncodingException;
import com.anxpp.io.utils.Calculator;
public class ServerHandler extends ChannelInboundHandlerAdapter {
	@Override
	public void channelRead(ChannelHandlerContext ctx, Object msg) throws UnsupportedEncodingException {
		ByteBuf in = (ByteBuf) msg;
		byte[] req = new byte[in.readableBytes()];
		in.readBytes(req);
		String body = new String(req,"utf-8");
		System.out.println("收到客户端消息:"+body);
		String calrResult = null;
		try{
			calrResult = Calculator.Instance.cal(body).toString();
		}catch(Exception e){
			calrResult = "错误的表达式:" + e.getMessage();
		}
		ctx.write(Unpooled.copiedBuffer(calrResult.getBytes()));
	}
	@Override
	public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
		ctx.flush();
	}
	/**
	 * 异常处理
	 */
	@Override
	public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
		cause.printStackTrace();
		ctx.close();
	}
}

2、客户端

    Client:

package com.anxpp.io.calculator.netty;
import io.netty.bootstrap.Bootstrap;
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.NioSocketChannel;
import java.util.Scanner;
public class Client implements Runnable{
    static ClientHandler client = new ClientHandler();
    public static void main(String[] args) throws Exception {
    	new Thread(new Client()).start();
		@SuppressWarnings("resource")
		Scanner scanner = new Scanner(System.in);
		while(client.sendMsg(scanner.nextLine()));
    }
	@Override
	public void run() {
        String host = "127.0.0.1";
        int port = 9090;
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        try {
            Bootstrap b = new Bootstrap();
            b.group(workerGroup);
            b.channel(NioSocketChannel.class);
            b.option(ChannelOption.SO_KEEPALIVE, true);
            b.handler(new ChannelInitializer<SocketChannel>() {
                @Override
                public void initChannel(SocketChannel ch) throws Exception {
                    ch.pipeline().addLast(client);
                }
            });
            ChannelFuture f = b.connect(host, port).sync();
            f.channel().closeFuture().sync();
        } catch (InterruptedException e) {
			e.printStackTrace();
		} finally {
            workerGroup.shutdownGracefully();
        }
	}
}

    ClientHandler:

package com.anxpp.io.calculator.netty;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import java.io.UnsupportedEncodingException;
public class ClientHandler extends ChannelInboundHandlerAdapter {
	ChannelHandlerContext ctx;
	/**
	 * tcp链路简历成功后调用
	 */
	@Override
	public void channelActive(ChannelHandlerContext ctx) throws Exception {
		this.ctx = ctx;
	}
	public boolean sendMsg(String msg){
		System.out.println("客户端发送消息:"+msg);
		byte[] req = msg.getBytes();
		ByteBuf m = Unpooled.buffer(req.length);
		m.writeBytes(req);
		ctx.writeAndFlush(m);
		return msg.equals("q")?false:true;
	}
	/**
	 * 收到服务器消息后调用
	 * @throws UnsupportedEncodingException 
	 */
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws UnsupportedEncodingException {
        ByteBuf buf = (ByteBuf) msg;
		byte[] req = new byte[buf.readableBytes()];
		buf.readBytes(req);
		String body = new String(req,"utf-8");
		System.out.println("服务器消息:"+body);
    }
    /**
     * 发生异常时调用
     */
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        cause.printStackTrace();
        ctx.close();
    }
}

3、用于计算的工具类

  1. package com.anxpp.io.utils;
  2. import javax.script.ScriptEngine;
  3. import javax.script.ScriptEngineManager;
  4. import javax.script.ScriptException;
  5. public enum Calculator {
  6. Instance;
  7. private final static ScriptEngine jse = new ScriptEngineManager().getEngineByName("JavaScript");
  8. public Object cal(String expression) throws ScriptException{
  9. return jse.eval(expression);
  10. }
  11. }

4、测试

    分别启动服务端和客户端,然后再客户端控制台输入表达式:

  1. 1+5+5+5+5+5
  2. 客户端发送消息:1+5+5+5+5+5
  3. 服务器消息:26
  4. 156158*458918+125615
  5. 客户端发送消息:156158*458918+125615
  6. 服务器消息:7.1663842659E10
  7. 1895612+555+5+5+5+5+5+5+5-5*4/4
  8. 客户端发送消息:1895612+555+5+5+5+5+5+5+5-5*4/4
  9. 服务器消息:1896197

    可以看到服务端返回的结果。

    查看服务端控制台:

  1. 服务器开启:9090
  2. 收到客户端消息:1+5+5+5+5+5
  3. 收到客户端消息:156158*458918+125615
  4. 收到客户端消息:1895612+555+5+5+5+5+5+5+5-5*4/4

5、更多

    相关文章:

    Java 网络IO编程总结(BIO、NIO、AIO均含完整实例代码)

    本文例子以及Java BIO NIO AIO例子的源码Git地址:https://github.com/anxpp/Java-IO.git

    后续会继续更新Netty相关内容,直到一个简陋的通讯服务器完成。

4
0
查看评论
发表评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场

菜鸟Java使用Netty

下载下来,搜索半天,如何使用Netty。。。。。。。。。。。网上找不到一篇类似的文章。对新手真是巨大的创伤啊! 还下载了Maven。现在还不知道这个东西干嘛的。好像对我使用Natty一点帮助都没有...
  • yulinxx
  • yulinxx
  • 2016-03-23 10:23
  • 1867

netty 入门使用

在网上找了例子:http://blog.csdn.net/bearray123/article/details/6185368,但原例子不知道是不是jar比较旧,有些方法不存在了。所以我也在这提下。之...
  • huaye2007
  • huaye2007
  • 2012-11-15 18:51
  • 22158

Netty——基本使用介绍

1.为什么选择Netty 上一篇文章我们已经了解了Socket通信(IO/NIO/AIO)编程,对于通信模型已经有了一个基本的认识。其实上一篇文章中,我们学习的仅仅是一个模型,如果想把这些真正的用于实...
  • haoyuyang
  • haoyuyang
  • 2016-11-20 19:51
  • 20890

3个netty5的例子,简单介绍netty的用法

3个netty5的例子,简单介绍netty的用法
  • tjbsl
  • tjbsl
  • 2016-04-01 18:49
  • 16916

Netty4详解二:开发第一个Netty应用程序

Netty入门二:开发第一个Netty应用程序 2.2、认识下Netty的Client和Server      一个Netty应用模型,如下图所示,但需要明白一点的是,我们写的Server会自动...
  • suifeng3051
  • suifeng3051
  • 2014-05-07 18:25
  • 27030

Java NIO框架Netty教程(一) – Hello Netty

先啰嗦两句,如果你还不知道Netty是做什么的能做什么。那可以先简单的搜索了解一下。我只能说Netty是一个NIO的框架,可以用于开发分布式的Java程序。具体能做什么,各位可以尽量发挥想象。技术,是...
  • kobejayandy
  • kobejayandy
  • 2013-09-09 22:05
  • 244429

Netty介绍(一)————为什么使用Netty

Netty的简单介绍Netty 是一个 NIO client-server(客户端服务器)框架,使用 Netty 可以快速开发网络应用,例如服务器和客户 端协议。 Netty 提供了一种新的方式来使开...
  • qq_25673113
  • qq_25673113
  • 2017-01-20 15:55
  • 1223

从dubbo看Netty使用

Netty是个高性能的Java网络传输框架,在很多中间件或者分布式框架中几乎都能看到它的身影。既然Netty这么受欢迎,那到底怎么把netty嵌入到我们的系统中了?笔者在几年前就接触了Netty,也开...
  • csujiangyu
  • csujiangyu
  • 2017-05-11 09:32
  • 5621

使用最新Netty实现一个简单的聊天程序

1、概述 Netty是由JBOSS提供的一个java开源框架。Netty提供异步的、事件驱动的网络应用程序框架和工具,用以快速开发高性能、高可靠性的网络服务器和客户端程序。 官网:h...
  • anxpp
  • anxpp
  • 2016-08-06 22:55
  • 6829

netty编解码之使用protobuf

netty编解码之使用protobufprotobuf这个序列化框架在我们公司使用了,我负责的模块中使用protobuf生成了一些model,然后使用了protostuff对缓存在redis中的数据进...
  • u012734441
  • u012734441
  • 2017-12-07 08:03
  • 294
    个人资料
    • 访问:749646次
    • 积分:5469
    • 等级:
    • 排名:第5698名
    • 原创:96篇
    • 转载:1篇
    • 译文:0篇
    • 评论:292条
    博客专栏
    其他信息