博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Netty入门-client/server
阅读量:7153 次
发布时间:2019-06-29

本文共 5444 字,大约阅读时间需要 18 分钟。

  hot3.png

一、环境准备

开发工具eclipse/idea(本人目前正在切换为idea),maven插件

最新版的netty包maven依赖

io.netty
netty-all
5.0.0.Alpha1

二、简单的client/server demo

功能:client端发送一个“query time order”字符串,server端接收到后返回当前服务器时间

Server端的代码

public class TimeServer {    public void bind(int port) throws  Exception{        EventLoopGroup bossGroup = new NioEventLoopGroup();        EventLoopGroup workerGroup = new NioEventLoopGroup();        ServerBootstrap b = new ServerBootstrap();        try {            b.group(bossGroup,workerGroup)                    .channel(NioServerSocketChannel.class)                    .option(ChannelOption.SO_BACKLOG, 1024)                    .childHandler(new ChildChannelHandler());            //绑定端口,同步等待成功            ChannelFuture f = b.bind(port).sync();            f.channel().closeFuture().sync();        } finally {            bossGroup.shutdownGracefully();            workerGroup.shutdownGracefully();        }    }    private class ChildChannelHandler extends ChannelInitializer
{ @Override protected void initChannel(SocketChannel ch) throws Exception { ch.pipeline().addLast(new TimeServerHandler()); System.out.println("server add time server handler"); } } public static void main(String[] args) throws Exception { int port = 8080; new TimeServer().bind(port); }}

TimeServer 首先创建了2个NioEventLoopGroup实例(NioEventLoopGroup是个线程组,它包含了一组NIO线程,专门用于网络事件的处理。),一个用于服务端接收客户端的链接,一个用于进行SokectChannel的网络读写。

ServerBootstrap是Netty用于启动NIO服务端的辅助启动类,group方法将两个线程组加入到进来。接着设置创建的Channel为NioServerSocketChannel。

然后配置NioServerSocketChannel的TCP参数,最后绑定I/O事件的处理器ChildChannelHandler。

f.channel().closeFuture().sync(); 方法进行阻塞,等待服务器链路关闭之后main函数才退出。

public class TimeServerHandler extends ChannelHandlerAdapter {    @Override    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {        ByteBuf buf = (ByteBuf)msg;        byte[] req = new byte[buf.readableBytes()];        buf.readBytes(req);        String body = new String(req,"UTF-8");        System.out.println("time server receive order is :"+body);        String res = "query time order".equals(body)?new Date().toString():"bad order";        ByteBuf resBuf = Unpooled.copiedBuffer(res.getBytes());        ctx.writeAndFlush(resBuf);    }    @Override    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {        System.out.println("server channel read complete……");        ctx.flush();    }    @Override    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {        System.out.println("server has exception :"+cause.getMessage());        ctx.close();    }}

TimeServerHandler 它用于对网络事件进行读写操作,通常我们只需要关注channelRead和exceptionCaught这两个方法

Client端代码

public class TimeClient {    public void connect(int port,String host) throws Exception {        EventLoopGroup group = new NioEventLoopGroup();        Bootstrap b = new Bootstrap();        try {            b.group(group).channel(NioSocketChannel.class)                    .option(ChannelOption.TCP_NODELAY, true)                    .handler(new ChannelInitializer
() { @Override protected void initChannel(SocketChannel ch) throws Exception { ch.pipeline().addLast(new TimeClientHandler()); System.out.println("client add time client handler"); } }); //发起异步连接操作 ChannelFuture f = b.connect(host,port).sync(); f.channel().closeFuture().sync(); } finally { group.shutdownGracefully(); } } public static void main(String[] args) throws Exception { int port = 8080; new TimeClient().connect(port,"127.0.0.1"); }}

首先创建客户端处理I/O读写的NioEventLoopGroup线程组,然后继续创建客户端辅助启动类Bootstrap,然后对其进行配置。它的Channel需要设置为NioSocketChannel,然后添加handler。

public class TimeClientHandler extends ChannelHandlerAdapter{    private final ByteBuf firstMessage;    public TimeClientHandler() {        byte[] res = "query time order".getBytes();        this.firstMessage = Unpooled.buffer(res.length);        firstMessage.writeBytes(res);    }    @Override    public void channelActive(ChannelHandlerContext ctx) throws Exception {        System.out.println("client channel active");        ctx.writeAndFlush(firstMessage);    }    @Override    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {        ByteBuf buf = (ByteBuf)msg;        byte[] req = new byte[buf.readableBytes()];        buf.readBytes(req);        System.out.println("Server time is : "+new String(req,"UTF-8"));    }    @Override    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {        System.out.println("client have exception : " + cause.getMessage());        ctx.close();    }}

这里重点关注channelActive,channelRead和exceptionCaught这三个方法。

当客户端和服务端TCP链路建立成功后,Netty的线程会调用channelActive方法,发送查询时间指令给服务端,调用ChannelHandlerContext的writeAndFlush方法将请求发送给服务端。服务端返回消息应答时,channelRead被调用。

运行效果

Server端输出

server add time server handlertime server receive order is :query time orderserver channel read complete……

Client端输出

client add time client handlerclient channel activeServer time is : Wed Dec 09 16:28:53 CST 2015

参考《Netty权威指南(第二版)》

转载于:https://my.oschina.net/zhdkn/blog/541670

你可能感兴趣的文章
【转载】遗传算法及matlab实现
查看>>
OAuth2.0基本流程
查看>>
C#数据导出到Excel
查看>>
微信打开网址添加在浏览器中打开提示
查看>>
KB奇遇记(6):搞笑的ERP项目团队
查看>>
iOS UI 21 线程
查看>>
学习jdbc连接数据库
查看>>
Linux时间子系统(十六) clockevent
查看>>
python 函数调用顺序
查看>>
使用 Newtonsoft.Json 操作 JSON 字符串
查看>>
线程4 同步和死锁
查看>>
详谈如何定制自己的博客园皮肤
查看>>
【CF】328 D. Super M
查看>>
HDU1517 A Multiplication Game
查看>>
js装饰者模式
查看>>
ThinkPHP中的函数库载入
查看>>
guava
查看>>
组合数据类型练习,综合练习
查看>>
Nodejs Guides(二)
查看>>
hdu 4286 Data Handler
查看>>