这次实现一个TimeServer和一个TimeClient 主要功能就是 Client连接到Server后 Server立即返回一个32位的时间整数,然后断开连接,客户端在接收到时间后,转换成可读格式 输出。
TimeServer 代码如下:
package netty.learn.time1;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelInitializer;
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;
/**
* What's the Class to do
* User: mzy
* Date: 13-6-20
* Time: 下午8:46
* Version:${VERSION}
*/
public class TimeServer {
private int port;
public void run(){
ServerBootstrap b = new ServerBootstrap();
EventLoopGroup boss = new NioEventLoopGroup();
EventLoopGroup worker = new NioEventLoopGroup();
b.group(boss,worker).channel(NioServerSocketChannel.class)
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel socketChannel) throws Exception {
socketChannel.pipeline().addLast(new LoggingHandler(LogLevel.INFO),new TimeServerHandler());
}
});
try{
b.bind(port).sync().channel().closeFuture().sync();
}catch (Exception e){
e.printStackTrace();
}finally {
boss.shutdownGracefully();
worker.shutdownGracefully();
}
}
public TimeServer(int port) {
this.port = port;
}
public static void main(String[] args) {
new TimeServer(8080).run();
}
}
TimeServerHandler代码如下:
package netty.learn.time1;
import io.netty.buffer.ByteBuf;
import io.netty.channel.*;
/**
* What's the Class to do
* User: mzy
* Date: 13-6-20
* Time: 下午8:48
* Version:${VERSION}
*/
public class TimeServerHandler extends ChannelInboundHandlerAdapter {
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
final ByteBuf time = ctx.alloc().buffer(4);
time.writeInt((int)(System.currentTimeMillis()/1000L+2208988800L));
final ChannelFuture future = ctx.write(time);
future.addListener(ChannelFutureListener.CLOSE);
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
cause.printStackTrace();
ctx.close();
}
}
当我们运行服务器端后可以用nc测试一下:
从nc的返回数据来看是四个字符,应该是在终端把32位的整数转换为了 4个8位的字符
这样的格式显然不可读,所以我们写一个Client用来转换数据
Client代码如下:
package netty.learn.time1;
import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import java.util.Date;
/**
* What's the Class to do
* User: mzy
* Date: 13-6-23
* Time: 下午2:34
* Version:${VERSION}
*/
class TimeClientHandler extends ChannelInboundHandlerAdapter{
@Override
public void messageReceived(ChannelHandlerContext ctx, MessageList<Object> msgs) throws Exception {
ByteBuf time = (ByteBuf) msgs.cast().get(0);
long currentTimeMillis = (time.readInt()-2208988800L)*1000L;
System.out.print(new Date(currentTimeMillis));
msgs.releaseAllAndRecycle();
ctx.close();
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
cause.printStackTrace();
ctx.close();
}
}
public class TimeClient {
private String host;
private int port;
public TimeClient(String host, int port) {
this.host = host;
this.port = port;
}
public void run(){
EventLoopGroup group = new NioEventLoopGroup();
Bootstrap b = new Bootstrap();
b.group(group).channel(NioSocketChannel.class)
.option(ChannelOption.SO_KEEPALIVE,true)
.handler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel socketChannel) throws Exception {
socketChannel.pipeline().addLast(new TimeClientHandler());
}
});
try{
b.connect(host,port).sync().channel().closeFuture().sync();
}catch (Exception e){
e.printStackTrace();
}finally {
group.shutdownGracefully();
}
}
public static void main(String[] args) {
new TimeClient("localhost",8080).run();
}
}
运行结果如下:
客户端打印请求到的时间后就断开连接。
ps:最后返回的时间不怎么对。。。