还是实现发送命令到服务端获取时间的功能,这里是Netty实现。
server端代码
package com.netty.server;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import java.util.Date;
/**
* Created by lcq on 12/5/2016.
*/
public class NettyTimeServer {
public static void main(String[] args) {
int port = 8080;
try {
new NettyTimeServer().bind(port);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private void bind(int port) throws InterruptedException {
EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workerGroup = new NioEventLoopGroup();
//以上两个group就是Reactor线程组,第一个是用于服务端接受客户端的连接,第二个是进行SocketChannel网络读写
try {
ServerBootstrap b = new ServerBootstrap();
b.group(bossGroup,workerGroup).channel(NioServerSocketChannel.class).option(ChannelOption.SO_BACKLOG,1024).childHandler(new ChildHandler());
ChannelFuture f = null;
f = b.bind(port).sync();
f.channel().closeFuture().sync();
}finally {
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}
/**
* ChildHandler 用于处理IO事件
*/
private class ChildHandler extends ChannelInitializer<SocketChannel> {
@Override
protected void initChannel(SocketChannel socketChannel) throws Exception {
socketChannel.pipeline().addLast(new TimeServerHandler());
}
private 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 : " + body);
String currentTime = "QUERY TIME ORDER".equalsIgnoreCase(body) ? new Date(System.currentTimeMillis()).toString() : "BAD ORDER";
ByteBuf resp = Unpooled.copiedBuffer(currentTime.getBytes());
ctx.write(resp);
}
@Override
public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
ctx.flush();
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
ctx.close();
}
}
}
}
client端
package com.netty.server;
import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
/**
* Created by lcq on 12/5/2016.
*/
public class NettyTimeClient {
public static void main(String[] args) {
int port = 8080;
try {
new NettyTimeClient().connect(port, "127.0.0.1");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private void connect(int port, String host) throws InterruptedException {
EventLoopGroup group = new NioEventLoopGroup();
try {
Bootstrap b = new Bootstrap();
b.group(group).channel(NioSocketChannel.class).option(ChannelOption.TCP_NODELAY, true).handler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel sc) throws Exception {
sc.pipeline().addLast(new TimeClientHandler());
}
});
//对比server端的启动:绑定的是SocketChannel,而不是ServerSocketChannel
ChannelFuture f = b.connect(host,port).sync();
f.channel().closeFuture().sync();
} finally {
group.shutdownGracefully();
}
}
private class TimeClientHandler extends ChannelHandlerAdapter {
private ByteBuf firtMessage;
public TimeClientHandler(){
byte[] req = "QUERY TIME ORDER".getBytes();
firtMessage = Unpooled.buffer(req.length);
firtMessage.writeBytes(req);
}
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
ctx.writeAndFlush(firtMessage);
}
@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("Now is : " + body);
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
ctx.close();
}
}
}
结果输出就不写了,和之前的程序输出一致。
对比之前的java nio实现的方式,Netty封装的还是非常简洁。同时单纯的对比Netty的Server和Client也能看出有许多相似之处。后期吧会逐步分析Netty实现的细节,一点点深入吧。
PS:比较晚了,推荐个英剧:黑镜,很好看。