├── README.md └── src └── com └── yiibai └── netty ├── discard ├── DiscardClient.java ├── DiscardClientHandler.java ├── DiscardServer.java └── DiscardServerHandler.java ├── echo ├── EchoClient.java ├── EchoClientHandler.java ├── EchoServer.java └── EchoServerHandler.java ├── pojo ├── TimeClient.java ├── TimeClientHandler.java ├── TimeDecoder.java ├── TimeEncoder.java ├── TimeServer.java ├── TimeServerHandler.java └── UnixTime.java ├── streambase ├── TimeClient.java ├── TimeClientHandler.java ├── TimeServer.java └── TimeServerHandler.java ├── streambase2 ├── TimeClient.java ├── TimeClientHandler.java ├── TimeDecoder.java ├── TimeServer.java └── TimeServerHandler.java └── time ├── TimeClient.java ├── TimeClientHandler.java ├── TimeServer.java └── TimeServerHandler.java /README.md: -------------------------------------------------------------------------------- 1 | # netty 2 | Netty教程 - Netty是一个java开源框架。Netty提供异步的、事件驱动的网络应用程序框架和工具,用以快速开发高性能、高可靠性的网络服务器和客户端程序。 3 | 这是 易百教程 http://www.yiibai.com/netty/  所述代码。有关代码实现讲解,请参考:http://www.yiibai.com/netty/ 4 | -------------------------------------------------------------------------------- /src/com/yiibai/netty/discard/DiscardClient.java: -------------------------------------------------------------------------------- 1 | 2 | package com.yiibai.netty.discard; 3 | 4 | import io.netty.bootstrap.Bootstrap; 5 | import io.netty.channel.ChannelFuture; 6 | import io.netty.channel.ChannelInitializer; 7 | import io.netty.channel.ChannelPipeline; 8 | import io.netty.channel.EventLoopGroup; 9 | import io.netty.channel.nio.NioEventLoopGroup; 10 | import io.netty.channel.socket.SocketChannel; 11 | import io.netty.channel.socket.nio.NioSocketChannel; 12 | import io.netty.handler.ssl.SslContext; 13 | import io.netty.handler.ssl.SslContextBuilder; 14 | import io.netty.handler.ssl.util.InsecureTrustManagerFactory; 15 | 16 | /** 17 | * Keeps sending random data to the specified address. 18 | */ 19 | public final class DiscardClient { 20 | 21 | static final boolean SSL = System.getProperty("ssl") != null; 22 | static final String HOST = System.getProperty("host", "127.0.0.1"); 23 | static final int PORT = Integer.parseInt(System.getProperty("port", "8080")); 24 | static final int SIZE = Integer.parseInt(System.getProperty("size", "256")); 25 | 26 | public static void main(String[] args) throws Exception { 27 | // Configure SSL. 28 | final SslContext sslCtx; 29 | if (SSL) { 30 | sslCtx = SslContextBuilder.forClient() 31 | .trustManager(InsecureTrustManagerFactory.INSTANCE).build(); 32 | } else { 33 | sslCtx = null; 34 | } 35 | 36 | EventLoopGroup group = new NioEventLoopGroup(); 37 | try { 38 | Bootstrap b = new Bootstrap(); 39 | b.group(group) 40 | .channel(NioSocketChannel.class) 41 | .handler(new ChannelInitializer() { 42 | @Override 43 | protected void initChannel(SocketChannel ch) throws Exception { 44 | ChannelPipeline p = ch.pipeline(); 45 | if (sslCtx != null) { 46 | p.addLast(sslCtx.newHandler(ch.alloc(), HOST, PORT)); 47 | } 48 | p.addLast(new DiscardClientHandler()); 49 | } 50 | }); 51 | 52 | // Make the connection attempt. 53 | ChannelFuture f = b.connect(HOST, PORT).sync(); 54 | 55 | // Wait until the connection is closed. 56 | f.channel().closeFuture().sync(); 57 | } finally { 58 | group.shutdownGracefully(); 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/com/yiibai/netty/discard/DiscardClientHandler.java: -------------------------------------------------------------------------------- 1 | package com.yiibai.netty.discard; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | import io.netty.channel.ChannelFuture; 5 | import io.netty.channel.ChannelFutureListener; 6 | import io.netty.channel.ChannelHandlerContext; 7 | import io.netty.channel.SimpleChannelInboundHandler; 8 | 9 | /** 10 | * Handles a client-side channel. 11 | */ 12 | public class DiscardClientHandler extends SimpleChannelInboundHandler { 13 | 14 | private ByteBuf content; 15 | private ChannelHandlerContext ctx; 16 | 17 | @Override 18 | public void channelActive(ChannelHandlerContext ctx) { 19 | this.ctx = ctx; 20 | 21 | // Initialize the message. 22 | content = ctx.alloc().directBuffer(DiscardClient.SIZE).writeZero(DiscardClient.SIZE); 23 | 24 | // Send the initial messages. 25 | generateTraffic(); 26 | } 27 | 28 | @Override 29 | public void channelInactive(ChannelHandlerContext ctx) { 30 | content.release(); 31 | } 32 | 33 | @Override 34 | public void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception { 35 | // Server is supposed to send nothing, but if it sends something, discard it. 36 | ctx.write(msg); // (1) 37 | ctx.flush(); // (2) 38 | } 39 | 40 | @Override 41 | public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { 42 | // Close the connection when an exception is raised. 43 | cause.printStackTrace(); 44 | ctx.close(); 45 | } 46 | 47 | long counter; 48 | 49 | private void generateTraffic() { 50 | // Flush the outbound buffer to the socket. 51 | // Once flushed, generate the same amount of traffic again. 52 | ctx.writeAndFlush(content.retainedDuplicate()).addListener(trafficGenerator); 53 | } 54 | 55 | private final ChannelFutureListener trafficGenerator = new ChannelFutureListener() { 56 | @Override 57 | public void operationComplete(ChannelFuture future) { 58 | if (future.isSuccess()) { 59 | generateTraffic(); 60 | } else { 61 | future.cause().printStackTrace(); 62 | future.channel().close(); 63 | } 64 | } 65 | }; 66 | } 67 | -------------------------------------------------------------------------------- /src/com/yiibai/netty/discard/DiscardServer.java: -------------------------------------------------------------------------------- 1 | package com.yiibai.netty.discard; 2 | 3 | import io.netty.bootstrap.ServerBootstrap; 4 | import io.netty.channel.ChannelFuture; 5 | import io.netty.channel.ChannelInitializer; 6 | import io.netty.channel.ChannelPipeline; 7 | import io.netty.channel.EventLoopGroup; 8 | import io.netty.channel.nio.NioEventLoopGroup; 9 | import io.netty.channel.socket.SocketChannel; 10 | import io.netty.channel.socket.nio.NioServerSocketChannel; 11 | import io.netty.handler.logging.LogLevel; 12 | import io.netty.handler.logging.LoggingHandler; 13 | import io.netty.handler.ssl.SslContext; 14 | import io.netty.handler.ssl.SslContextBuilder; 15 | import io.netty.handler.ssl.util.SelfSignedCertificate; 16 | 17 | /** 18 | * Discards any incoming data. 19 | */ 20 | public final class DiscardServer { 21 | 22 | static final boolean SSL = System.getProperty("ssl") != null; 23 | static final int PORT = Integer.parseInt(System.getProperty("port", "8080")); 24 | 25 | public static void main(String[] args) throws Exception { 26 | // Configure SSL. 27 | final SslContext sslCtx; 28 | if (SSL) { 29 | SelfSignedCertificate ssc = new SelfSignedCertificate(); 30 | sslCtx = SslContextBuilder.forServer(ssc.certificate(), ssc.privateKey()).build(); 31 | } else { 32 | sslCtx = null; 33 | } 34 | 35 | EventLoopGroup bossGroup = new NioEventLoopGroup(1); 36 | EventLoopGroup workerGroup = new NioEventLoopGroup(); 37 | try { 38 | ServerBootstrap b = new ServerBootstrap(); 39 | b.group(bossGroup, workerGroup) 40 | .channel(NioServerSocketChannel.class) 41 | .handler(new LoggingHandler(LogLevel.INFO)) 42 | .childHandler(new ChannelInitializer() { 43 | @Override 44 | public void initChannel(SocketChannel ch) { 45 | ChannelPipeline p = ch.pipeline(); 46 | if (sslCtx != null) { 47 | p.addLast(sslCtx.newHandler(ch.alloc())); 48 | } 49 | p.addLast(new DiscardServerHandler()); 50 | } 51 | }); 52 | 53 | // Bind and start to accept incoming connections. 54 | ChannelFuture f = b.bind(PORT).sync(); 55 | 56 | // Wait until the server socket is closed. 57 | // In this example, this does not happen, but you can do that to gracefully 58 | // shut down your server. 59 | f.channel().closeFuture().sync(); 60 | } finally { 61 | workerGroup.shutdownGracefully(); 62 | bossGroup.shutdownGracefully(); 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/com/yiibai/netty/discard/DiscardServerHandler.java: -------------------------------------------------------------------------------- 1 | package com.yiibai.netty.discard; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | 5 | import io.netty.channel.ChannelHandlerContext; 6 | import io.netty.channel.ChannelInboundHandlerAdapter; 7 | import io.netty.util.ReferenceCountUtil; 8 | 9 | /** 10 | * Handles a server-side channel. 11 | */ 12 | public class DiscardServerHandler extends ChannelInboundHandlerAdapter { // (1) 13 | 14 | @Override 15 | public void channelRead(ChannelHandlerContext ctx, Object msg) { // (2) 16 | // Discard the received data silently. 17 | System.out.println("Yes, A new client in = " + ctx.name()); 18 | } 19 | 20 | @Override 21 | public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { // (4) 22 | // Close the connection when an exception is raised. 23 | cause.printStackTrace(); 24 | ctx.close(); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/com/yiibai/netty/echo/EchoClient.java: -------------------------------------------------------------------------------- 1 | 2 | package com.yiibai.netty.echo; 3 | 4 | import io.netty.bootstrap.Bootstrap; 5 | import io.netty.channel.ChannelFuture; 6 | import io.netty.channel.ChannelInitializer; 7 | import io.netty.channel.ChannelOption; 8 | import io.netty.channel.ChannelPipeline; 9 | import io.netty.channel.EventLoopGroup; 10 | import io.netty.channel.nio.NioEventLoopGroup; 11 | import io.netty.channel.socket.SocketChannel; 12 | import io.netty.channel.socket.nio.NioSocketChannel; 13 | import io.netty.handler.ssl.SslContext; 14 | import io.netty.handler.ssl.SslContextBuilder; 15 | import io.netty.handler.ssl.util.InsecureTrustManagerFactory; 16 | 17 | /** 18 | * Sends one message when a connection is open and echoes back any received 19 | * data to the server. Simply put, the echo client initiates the ping-pong 20 | * traffic between the echo client and server by sending the first message to 21 | * the server. 22 | */ 23 | public final class EchoClient { 24 | 25 | static final boolean SSL = System.getProperty("ssl") != null; 26 | static final String HOST = System.getProperty("host", "127.0.0.1"); 27 | static final int PORT = Integer.parseInt(System.getProperty("port", "8007")); 28 | static final int SIZE = Integer.parseInt(System.getProperty("size", "256")); 29 | 30 | public static void main(String[] args) throws Exception { 31 | // Configure SSL.git 32 | final SslContext sslCtx; 33 | if (SSL) { 34 | sslCtx = SslContextBuilder.forClient() 35 | .trustManager(InsecureTrustManagerFactory.INSTANCE).build(); 36 | } else { 37 | sslCtx = null; 38 | } 39 | 40 | // Configure the client. 41 | EventLoopGroup group = new NioEventLoopGroup(); 42 | try { 43 | Bootstrap b = new Bootstrap(); 44 | b.group(group) 45 | .channel(NioSocketChannel.class) 46 | .option(ChannelOption.TCP_NODELAY, true) 47 | .handler(new ChannelInitializer() { 48 | @Override 49 | public void initChannel(SocketChannel ch) throws Exception { 50 | ChannelPipeline p = ch.pipeline(); 51 | if (sslCtx != null) { 52 | p.addLast(sslCtx.newHandler(ch.alloc(), HOST, PORT)); 53 | } 54 | //p.addLast(new LoggingHandler(LogLevel.INFO)); 55 | p.addLast(new EchoClientHandler()); 56 | } 57 | }); 58 | 59 | // Start the client. 60 | ChannelFuture f = b.connect(HOST, PORT).sync(); 61 | 62 | // Wait until the connection is closed. 63 | f.channel().closeFuture().sync(); 64 | } finally { 65 | // Shut down the event loop to terminate all threads. 66 | group.shutdownGracefully(); 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/com/yiibai/netty/echo/EchoClientHandler.java: -------------------------------------------------------------------------------- 1 | package com.yiibai.netty.echo; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | import io.netty.buffer.Unpooled; 5 | import io.netty.channel.ChannelHandlerContext; 6 | import io.netty.channel.ChannelInboundHandlerAdapter; 7 | import io.netty.util.CharsetUtil; 8 | 9 | /** 10 | * Handler implementation for the echo client. It initiates the ping-pong 11 | * traffic between the echo client and server by sending the first message to 12 | * the server. 13 | */ 14 | public class EchoClientHandler extends ChannelInboundHandlerAdapter { 15 | 16 | private final ByteBuf firstMessage; 17 | 18 | /** 19 | * Creates a client-side handler. 20 | */ 21 | public EchoClientHandler() { 22 | firstMessage = Unpooled.buffer(EchoClient.SIZE); 23 | for (int i = 0; i < firstMessage.capacity(); i ++) { 24 | firstMessage.writeByte((byte) i); 25 | } 26 | } 27 | 28 | @Override 29 | public void channelActive(ChannelHandlerContext ctx) { 30 | System.out.println("Connected"); 31 | ctx.writeAndFlush(Unpooled.copiedBuffer("This msg from clien!", CharsetUtil.UTF_8)); 32 | //ctx.writeAndFlush(firstMessage); 33 | } 34 | 35 | @Override 36 | public void channelRead(ChannelHandlerContext ctx, Object msg) { 37 | ByteBuf in = (ByteBuf) msg; 38 | System.out.println("Msg Form Server: " + in.toString(CharsetUtil.UTF_8)); 39 | //ctx.write(msg); 40 | } 41 | 42 | @Override 43 | public void channelReadComplete(ChannelHandlerContext ctx) { 44 | ctx.flush(); 45 | } 46 | 47 | @Override 48 | public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { 49 | // Close the connection when an exception is raised. 50 | cause.printStackTrace(); 51 | ctx.close(); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/com/yiibai/netty/echo/EchoServer.java: -------------------------------------------------------------------------------- 1 | package com.yiibai.netty.echo; 2 | 3 | import io.netty.bootstrap.ServerBootstrap; 4 | import io.netty.channel.ChannelFuture; 5 | import io.netty.channel.ChannelInitializer; 6 | import io.netty.channel.ChannelOption; 7 | import io.netty.channel.ChannelPipeline; 8 | import io.netty.channel.EventLoopGroup; 9 | import io.netty.channel.nio.NioEventLoopGroup; 10 | import io.netty.channel.socket.SocketChannel; 11 | import io.netty.channel.socket.nio.NioServerSocketChannel; 12 | import io.netty.handler.logging.LogLevel; 13 | import io.netty.handler.logging.LoggingHandler; 14 | import io.netty.handler.ssl.SslContext; 15 | import io.netty.handler.ssl.SslContextBuilder; 16 | import io.netty.handler.ssl.util.SelfSignedCertificate; 17 | 18 | /** 19 | * Echoes back any received data from a client. 20 | */ 21 | public final class EchoServer { 22 | 23 | static final boolean SSL = System.getProperty("ssl") != null; 24 | static final int PORT = Integer.parseInt(System.getProperty("port", "8007")); 25 | 26 | public static void main(String[] args) throws Exception { 27 | // Configure SSL. 28 | final SslContext sslCtx; 29 | if (SSL) { 30 | SelfSignedCertificate ssc = new SelfSignedCertificate(); 31 | sslCtx = SslContextBuilder.forServer(ssc.certificate(), ssc.privateKey()).build(); 32 | } else { 33 | sslCtx = null; 34 | } 35 | 36 | // Configure the server. 37 | EventLoopGroup bossGroup = new NioEventLoopGroup(1); 38 | EventLoopGroup workerGroup = new NioEventLoopGroup(); 39 | try { 40 | ServerBootstrap b = new ServerBootstrap(); 41 | b.group(bossGroup, workerGroup) 42 | .channel(NioServerSocketChannel.class) 43 | .option(ChannelOption.SO_BACKLOG, 100) 44 | .handler(new LoggingHandler(LogLevel.INFO)) 45 | .childHandler(new ChannelInitializer() { 46 | @Override 47 | public void initChannel(SocketChannel ch) throws Exception { 48 | ChannelPipeline p = ch.pipeline(); 49 | if (sslCtx != null) { 50 | p.addLast(sslCtx.newHandler(ch.alloc())); 51 | } 52 | //p.addLast(new LoggingHandler(LogLevel.INFO)); 53 | p.addLast(new EchoServerHandler()); 54 | } 55 | }); 56 | 57 | // Start the server. 58 | ChannelFuture f = b.bind(PORT).sync(); 59 | 60 | // Wait until the server socket is closed. 61 | f.channel().closeFuture().sync(); 62 | } finally { 63 | // Shut down all event loops to terminate all threads. 64 | bossGroup.shutdownGracefully(); 65 | workerGroup.shutdownGracefully(); 66 | } 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/com/yiibai/netty/echo/EchoServerHandler.java: -------------------------------------------------------------------------------- 1 | package com.yiibai.netty.echo; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | import io.netty.channel.ChannelHandler.Sharable; 5 | import io.netty.channel.ChannelHandlerContext; 6 | import io.netty.channel.ChannelInboundHandlerAdapter; 7 | import io.netty.util.CharsetUtil; 8 | 9 | /** 10 | * Handler implementation for the echo server. 11 | */ 12 | @Sharable 13 | public class EchoServerHandler extends ChannelInboundHandlerAdapter { 14 | 15 | @Override 16 | public void channelRead(ChannelHandlerContext ctx, Object msg) { 17 | ByteBuf in = (ByteBuf) msg; 18 | System.out.println("Server received: " + in.toString(CharsetUtil.UTF_8)); 19 | ctx.write(in); 20 | //ctx.write(msg); 21 | ctx.flush(); 22 | } 23 | 24 | @Override 25 | public void channelReadComplete(ChannelHandlerContext ctx) { 26 | ctx.flush(); 27 | } 28 | 29 | @Override 30 | public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { 31 | // Close the connection when an exception is raised. 32 | cause.printStackTrace(); 33 | ctx.close(); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/com/yiibai/netty/pojo/TimeClient.java: -------------------------------------------------------------------------------- 1 | 2 | package com.yiibai.netty.pojo; 3 | import io.netty.bootstrap.Bootstrap; 4 | import io.netty.channel.ChannelFuture; 5 | import io.netty.channel.ChannelInitializer; 6 | import io.netty.channel.ChannelOption; 7 | import io.netty.channel.EventLoopGroup; 8 | import io.netty.channel.nio.NioEventLoopGroup; 9 | import io.netty.channel.socket.SocketChannel; 10 | import io.netty.channel.socket.nio.NioSocketChannel; 11 | 12 | public class TimeClient { 13 | 14 | public static void main(String[] args) throws Exception { 15 | 16 | String host = "127.0.0.1";// args[0]; 17 | int port = 8080;//Integer.parseInt(args[1]); 18 | EventLoopGroup workerGroup = new NioEventLoopGroup(); 19 | 20 | try { 21 | Bootstrap b = new Bootstrap(); // (1) 22 | b.group(workerGroup); // (2) 23 | b.channel(NioSocketChannel.class); // (3) 24 | b.option(ChannelOption.SO_KEEPALIVE, true); // (4) 25 | /** 26 | b.handler(new ChannelInitializer() { 27 | @Override 28 | public void initChannel(SocketChannel ch) throws Exception { 29 | ch.pipeline().addLast(new TimeClientHandler()); 30 | } 31 | });*/ 32 | 33 | b.handler(new ChannelInitializer() { 34 | @Override 35 | public void initChannel(SocketChannel ch) throws Exception { 36 | ch.pipeline().addLast(new TimeDecoder(), new TimeClientHandler()); 37 | } 38 | }); 39 | 40 | // 启动客户端 41 | ChannelFuture f = b.connect(host, port).sync(); // (5) 42 | 43 | // 等待连接关闭 44 | f.channel().closeFuture().sync(); 45 | } finally { 46 | workerGroup.shutdownGracefully(); 47 | } 48 | } 49 | } -------------------------------------------------------------------------------- /src/com/yiibai/netty/pojo/TimeClientHandler.java: -------------------------------------------------------------------------------- 1 | package com.yiibai.netty.pojo; 2 | 3 | import java.text.SimpleDateFormat; 4 | import java.util.Date; 5 | 6 | import io.netty.buffer.ByteBuf; 7 | import io.netty.channel.ChannelHandlerContext; 8 | import io.netty.channel.ChannelInboundHandlerAdapter; 9 | import java.util.Date; 10 | 11 | public class TimeClientHandler extends ChannelInboundHandlerAdapter { 12 | private ByteBuf buf; 13 | 14 | @Override 15 | public void handlerAdded(ChannelHandlerContext ctx) { 16 | buf = ctx.alloc().buffer(4); // (1) 17 | } 18 | 19 | @Override 20 | public void handlerRemoved(ChannelHandlerContext ctx) { 21 | buf.release(); // (1) 22 | buf = null; 23 | } 24 | 25 | /** 26 | @Override 27 | public void channelRead(ChannelHandlerContext ctx, Object msg) { 28 | ByteBuf m = (ByteBuf) msg; 29 | buf.writeBytes(m); // (2) 30 | m.release(); 31 | 32 | if (buf.readableBytes() >= 4) { // (3) 33 | long currentTimeMillis = (buf.readUnsignedInt() - 2208988800L) * 1000L; 34 | System.out.println(new Date(currentTimeMillis)); 35 | ctx.close(); 36 | } 37 | }*/ 38 | 39 | @Override 40 | public void channelRead(ChannelHandlerContext ctx, Object msg) { 41 | UnixTime m = (UnixTime) msg; 42 | System.out.println(m); 43 | ctx.close(); 44 | } 45 | 46 | @Override 47 | public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { 48 | cause.printStackTrace(); 49 | ctx.close(); 50 | } 51 | } -------------------------------------------------------------------------------- /src/com/yiibai/netty/pojo/TimeDecoder.java: -------------------------------------------------------------------------------- 1 | package com.yiibai.netty.pojo; 2 | 3 | import java.util.List; 4 | 5 | import io.netty.buffer.ByteBuf; 6 | import io.netty.channel.ChannelHandlerContext; 7 | import io.netty.handler.codec.ByteToMessageDecoder; 8 | 9 | public class TimeDecoder extends ByteToMessageDecoder { // (1) 10 | /** 11 | @Override 12 | protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out) { // (2) 13 | if (in.readableBytes() < 4) { 14 | return; // (3) 15 | } 16 | 17 | out.add(in.readBytes(4)); // (4) 18 | }*/ 19 | 20 | @Override 21 | protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out) { 22 | if (in.readableBytes() < 4) { 23 | return; 24 | } 25 | 26 | out.add(new UnixTime(in.readUnsignedInt())); 27 | } 28 | } -------------------------------------------------------------------------------- /src/com/yiibai/netty/pojo/TimeEncoder.java: -------------------------------------------------------------------------------- 1 | package com.yiibai.netty.pojo; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | import io.netty.channel.ChannelHandlerContext; 5 | import io.netty.channel.ChannelOutboundHandlerAdapter; 6 | import io.netty.channel.ChannelPromise; 7 | 8 | public class TimeEncoder extends ChannelOutboundHandlerAdapter { 9 | @Override 10 | public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) { 11 | UnixTime m = (UnixTime) msg; 12 | ByteBuf encoded = ctx.alloc().buffer(4); 13 | encoded.writeInt((int)m.value()); 14 | ctx.write(encoded, promise); // (1) 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/com/yiibai/netty/pojo/TimeServer.java: -------------------------------------------------------------------------------- 1 | package com.yiibai.netty.pojo; 2 | 3 | import io.netty.bootstrap.ServerBootstrap; 4 | 5 | import io.netty.channel.ChannelFuture; 6 | import io.netty.channel.ChannelInitializer; 7 | import io.netty.channel.ChannelOption; 8 | import io.netty.channel.EventLoopGroup; 9 | import io.netty.channel.nio.NioEventLoopGroup; 10 | import io.netty.channel.socket.SocketChannel; 11 | import io.netty.channel.socket.nio.NioServerSocketChannel; 12 | 13 | /** 14 | * 时间服务器 15 | */ 16 | public class TimeServer { 17 | 18 | private int port; 19 | 20 | public TimeServer(int port) { 21 | this.port = port; 22 | } 23 | 24 | public void run() throws Exception { 25 | EventLoopGroup bossGroup = new NioEventLoopGroup(); // (1) 26 | EventLoopGroup workerGroup = new NioEventLoopGroup(); 27 | try { 28 | ServerBootstrap b = new ServerBootstrap(); // (2) 29 | b.group(bossGroup, workerGroup) 30 | .channel(NioServerSocketChannel.class) // (3) 31 | .childHandler(new ChannelInitializer() { // (4) 32 | @Override 33 | public void initChannel(SocketChannel ch) throws Exception { 34 | //ch.pipeline().addLast(new TimeServerHandler()); 35 | ch.pipeline().addLast(new TimeServerHandler()); 36 | ch.pipeline().addFirst(new TimeEncoder()); 37 | } 38 | }) 39 | .option(ChannelOption.SO_BACKLOG, 128) // (5) 40 | .childOption(ChannelOption.SO_KEEPALIVE, true); // (6) 41 | 42 | // 绑定端口,开始接收进来的连接 43 | ChannelFuture f = b.bind(port).sync(); // (7) 44 | 45 | // 等待服务器 socket 关闭 。 46 | // 在这个例子中,这不会发生,但你可以优雅地关闭你的服务器。 47 | f.channel().closeFuture().sync(); 48 | } finally { 49 | workerGroup.shutdownGracefully(); 50 | bossGroup.shutdownGracefully(); 51 | } 52 | } 53 | 54 | public static void main(String[] args) throws Exception { 55 | int port; 56 | if (args.length > 0) { 57 | port = Integer.parseInt(args[0]); 58 | } else { 59 | port = 8080; 60 | } 61 | new TimeServer(port).run(); 62 | } 63 | } -------------------------------------------------------------------------------- /src/com/yiibai/netty/pojo/TimeServerHandler.java: -------------------------------------------------------------------------------- 1 | package com.yiibai.netty.pojo; 2 | import io.netty.buffer.ByteBuf; 3 | import io.netty.channel.ChannelFuture; 4 | import io.netty.channel.ChannelFutureListener; 5 | import io.netty.channel.ChannelHandlerContext; 6 | import io.netty.channel.ChannelInboundHandlerAdapter; 7 | 8 | public class TimeServerHandler extends ChannelInboundHandlerAdapter { 9 | /** 10 | @Override 11 | public void channelActive(final ChannelHandlerContext ctx) { // (1) 12 | final ByteBuf time = ctx.alloc().buffer(4); // (2) 13 | time.writeInt((int) (System.currentTimeMillis() / 1000L + 2208988800L)); 14 | 15 | final ChannelFuture f = ctx.writeAndFlush(time); // (3) 16 | f.addListener(new ChannelFutureListener() { 17 | @Override 18 | public void operationComplete(ChannelFuture future) { 19 | assert f == future; 20 | ctx.close(); 21 | } 22 | }); // (4) 23 | }*/ 24 | 25 | @Override 26 | public void channelActive(ChannelHandlerContext ctx) { 27 | ChannelFuture f = ctx.writeAndFlush(new UnixTime()); 28 | f.addListener(ChannelFutureListener.CLOSE); 29 | } 30 | 31 | @Override 32 | public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { 33 | cause.printStackTrace(); 34 | ctx.close(); 35 | } 36 | } -------------------------------------------------------------------------------- /src/com/yiibai/netty/pojo/UnixTime.java: -------------------------------------------------------------------------------- 1 | package com.yiibai.netty.pojo; 2 | 3 | import java.text.SimpleDateFormat; 4 | import java.util.Date; 5 | 6 | public class UnixTime { 7 | 8 | private final long value; 9 | 10 | public UnixTime() { 11 | this(System.currentTimeMillis() / 1000L + 2208988800L); 12 | } 13 | 14 | public UnixTime(long value) { 15 | this.value = value; 16 | } 17 | 18 | public long value() { 19 | return value; 20 | } 21 | 22 | @Override 23 | public String toString() { 24 | Date date = new Date((value() - 2208988800L) * 1000L); 25 | SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 26 | String dateString = formatter.format(date); 27 | return dateString; 28 | } 29 | } -------------------------------------------------------------------------------- /src/com/yiibai/netty/streambase/TimeClient.java: -------------------------------------------------------------------------------- 1 | 2 | package com.yiibai.netty.streambase; 3 | import io.netty.bootstrap.Bootstrap; 4 | import io.netty.channel.ChannelFuture; 5 | import io.netty.channel.ChannelInitializer; 6 | import io.netty.channel.ChannelOption; 7 | import io.netty.channel.EventLoopGroup; 8 | import io.netty.channel.nio.NioEventLoopGroup; 9 | import io.netty.channel.socket.SocketChannel; 10 | import io.netty.channel.socket.nio.NioSocketChannel; 11 | 12 | public class TimeClient { 13 | 14 | public static void main(String[] args) throws Exception { 15 | 16 | String host = "127.0.0.1";// args[0]; 17 | int port = 8080;//Integer.parseInt(args[1]); 18 | EventLoopGroup workerGroup = new NioEventLoopGroup(); 19 | 20 | try { 21 | Bootstrap b = new Bootstrap(); // (1) 22 | b.group(workerGroup); // (2) 23 | b.channel(NioSocketChannel.class); // (3) 24 | b.option(ChannelOption.SO_KEEPALIVE, true); // (4) 25 | b.handler(new ChannelInitializer() { 26 | @Override 27 | public void initChannel(SocketChannel ch) throws Exception { 28 | ch.pipeline().addLast(new TimeClientHandler()); 29 | } 30 | }); 31 | 32 | // 启动客户端 33 | ChannelFuture f = b.connect(host, port).sync(); // (5) 34 | 35 | // 等待连接关闭 36 | f.channel().closeFuture().sync(); 37 | } finally { 38 | workerGroup.shutdownGracefully(); 39 | } 40 | } 41 | } -------------------------------------------------------------------------------- /src/com/yiibai/netty/streambase/TimeClientHandler.java: -------------------------------------------------------------------------------- 1 | package com.yiibai.netty.streambase; 2 | 3 | import java.text.SimpleDateFormat; 4 | import java.util.Date; 5 | 6 | import io.netty.buffer.ByteBuf; 7 | import io.netty.channel.ChannelHandlerContext; 8 | import io.netty.channel.ChannelInboundHandlerAdapter; 9 | import java.util.Date; 10 | 11 | public class TimeClientHandler extends ChannelInboundHandlerAdapter { 12 | private ByteBuf buf; 13 | 14 | @Override 15 | public void handlerAdded(ChannelHandlerContext ctx) { 16 | buf = ctx.alloc().buffer(4); // (1) 17 | } 18 | 19 | @Override 20 | public void handlerRemoved(ChannelHandlerContext ctx) { 21 | buf.release(); // (1) 22 | buf = null; 23 | } 24 | 25 | @Override 26 | public void channelRead(ChannelHandlerContext ctx, Object msg) { 27 | ByteBuf m = (ByteBuf) msg; 28 | buf.writeBytes(m); // (2) 29 | m.release(); 30 | 31 | if (buf.readableBytes() >= 4) { // (3) 32 | long currentTimeMillis = (buf.readUnsignedInt() - 2208988800L) * 1000L; 33 | System.out.println(new Date(currentTimeMillis)); 34 | ctx.close(); 35 | } 36 | } 37 | 38 | @Override 39 | public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { 40 | cause.printStackTrace(); 41 | ctx.close(); 42 | } 43 | } -------------------------------------------------------------------------------- /src/com/yiibai/netty/streambase/TimeServer.java: -------------------------------------------------------------------------------- 1 | package com.yiibai.netty.streambase; 2 | 3 | import io.netty.bootstrap.ServerBootstrap; 4 | 5 | import io.netty.channel.ChannelFuture; 6 | import io.netty.channel.ChannelInitializer; 7 | import io.netty.channel.ChannelOption; 8 | import io.netty.channel.EventLoopGroup; 9 | import io.netty.channel.nio.NioEventLoopGroup; 10 | import io.netty.channel.socket.SocketChannel; 11 | import io.netty.channel.socket.nio.NioServerSocketChannel; 12 | 13 | /** 14 | * 时间服务器 15 | */ 16 | public class TimeServer { 17 | 18 | private int port; 19 | 20 | public TimeServer(int port) { 21 | this.port = port; 22 | } 23 | 24 | public void run() throws Exception { 25 | EventLoopGroup bossGroup = new NioEventLoopGroup(); // (1) 26 | EventLoopGroup workerGroup = new NioEventLoopGroup(); 27 | try { 28 | ServerBootstrap b = new ServerBootstrap(); // (2) 29 | b.group(bossGroup, workerGroup) 30 | .channel(NioServerSocketChannel.class) // (3) 31 | .childHandler(new ChannelInitializer() { // (4) 32 | @Override 33 | public void initChannel(SocketChannel ch) throws Exception { 34 | ch.pipeline().addLast(new TimeServerHandler()); 35 | } 36 | }) 37 | .option(ChannelOption.SO_BACKLOG, 128) // (5) 38 | .childOption(ChannelOption.SO_KEEPALIVE, true); // (6) 39 | 40 | // 绑定端口,开始接收进来的连接 41 | ChannelFuture f = b.bind(port).sync(); // (7) 42 | 43 | // 等待服务器 socket 关闭 。 44 | // 在这个例子中,这不会发生,但你可以优雅地关闭你的服务器。 45 | f.channel().closeFuture().sync(); 46 | } finally { 47 | workerGroup.shutdownGracefully(); 48 | bossGroup.shutdownGracefully(); 49 | } 50 | } 51 | 52 | public static void main(String[] args) throws Exception { 53 | int port; 54 | if (args.length > 0) { 55 | port = Integer.parseInt(args[0]); 56 | } else { 57 | port = 8080; 58 | } 59 | new TimeServer(port).run(); 60 | } 61 | } -------------------------------------------------------------------------------- /src/com/yiibai/netty/streambase/TimeServerHandler.java: -------------------------------------------------------------------------------- 1 | package com.yiibai.netty.streambase; 2 | import io.netty.buffer.ByteBuf; 3 | import io.netty.channel.ChannelFuture; 4 | import io.netty.channel.ChannelFutureListener; 5 | import io.netty.channel.ChannelHandlerContext; 6 | import io.netty.channel.ChannelInboundHandlerAdapter; 7 | 8 | public class TimeServerHandler extends ChannelInboundHandlerAdapter { 9 | 10 | @Override 11 | public void channelActive(final ChannelHandlerContext ctx) { // (1) 12 | final ByteBuf time = ctx.alloc().buffer(4); // (2) 13 | time.writeInt((int) (System.currentTimeMillis() / 1000L + 2208988800L)); 14 | 15 | final ChannelFuture f = ctx.writeAndFlush(time); // (3) 16 | f.addListener(new ChannelFutureListener() { 17 | @Override 18 | public void operationComplete(ChannelFuture future) { 19 | assert f == future; 20 | ctx.close(); 21 | } 22 | }); // (4) 23 | } 24 | 25 | @Override 26 | public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { 27 | cause.printStackTrace(); 28 | ctx.close(); 29 | } 30 | } -------------------------------------------------------------------------------- /src/com/yiibai/netty/streambase2/TimeClient.java: -------------------------------------------------------------------------------- 1 | 2 | package com.yiibai.netty.streambase2; 3 | import io.netty.bootstrap.Bootstrap; 4 | import io.netty.channel.ChannelFuture; 5 | import io.netty.channel.ChannelInitializer; 6 | import io.netty.channel.ChannelOption; 7 | import io.netty.channel.EventLoopGroup; 8 | import io.netty.channel.nio.NioEventLoopGroup; 9 | import io.netty.channel.socket.SocketChannel; 10 | import io.netty.channel.socket.nio.NioSocketChannel; 11 | 12 | public class TimeClient { 13 | 14 | public static void main(String[] args) throws Exception { 15 | 16 | String host = "127.0.0.1";// args[0]; 17 | int port = 8080;//Integer.parseInt(args[1]); 18 | EventLoopGroup workerGroup = new NioEventLoopGroup(); 19 | 20 | try { 21 | Bootstrap b = new Bootstrap(); // (1) 22 | b.group(workerGroup); // (2) 23 | b.channel(NioSocketChannel.class); // (3) 24 | b.option(ChannelOption.SO_KEEPALIVE, true); // (4) 25 | /** 26 | b.handler(new ChannelInitializer() { 27 | @Override 28 | public void initChannel(SocketChannel ch) throws Exception { 29 | ch.pipeline().addLast(new TimeClientHandler()); 30 | } 31 | });*/ 32 | 33 | b.handler(new ChannelInitializer() { 34 | @Override 35 | public void initChannel(SocketChannel ch) throws Exception { 36 | ch.pipeline().addLast(new TimeDecoder(), new TimeClientHandler()); 37 | } 38 | }); 39 | 40 | // 启动客户端 41 | ChannelFuture f = b.connect(host, port).sync(); // (5) 42 | 43 | // 等待连接关闭 44 | f.channel().closeFuture().sync(); 45 | } finally { 46 | workerGroup.shutdownGracefully(); 47 | } 48 | } 49 | } -------------------------------------------------------------------------------- /src/com/yiibai/netty/streambase2/TimeClientHandler.java: -------------------------------------------------------------------------------- 1 | package com.yiibai.netty.streambase2; 2 | 3 | import java.text.SimpleDateFormat; 4 | import java.util.Date; 5 | 6 | import io.netty.buffer.ByteBuf; 7 | import io.netty.channel.ChannelHandlerContext; 8 | import io.netty.channel.ChannelInboundHandlerAdapter; 9 | import java.util.Date; 10 | 11 | public class TimeClientHandler extends ChannelInboundHandlerAdapter { 12 | private ByteBuf buf; 13 | 14 | @Override 15 | public void handlerAdded(ChannelHandlerContext ctx) { 16 | buf = ctx.alloc().buffer(4); // (1) 17 | } 18 | 19 | @Override 20 | public void handlerRemoved(ChannelHandlerContext ctx) { 21 | buf.release(); // (1) 22 | buf = null; 23 | } 24 | 25 | @Override 26 | public void channelRead(ChannelHandlerContext ctx, Object msg) { 27 | ByteBuf m = (ByteBuf) msg; 28 | buf.writeBytes(m); // (2) 29 | m.release(); 30 | 31 | if (buf.readableBytes() >= 4) { // (3) 32 | long currentTimeMillis = (buf.readUnsignedInt() - 2208988800L) * 1000L; 33 | System.out.println(new Date(currentTimeMillis)); 34 | ctx.close(); 35 | } 36 | } 37 | 38 | @Override 39 | public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { 40 | cause.printStackTrace(); 41 | ctx.close(); 42 | } 43 | } -------------------------------------------------------------------------------- /src/com/yiibai/netty/streambase2/TimeDecoder.java: -------------------------------------------------------------------------------- 1 | package com.yiibai.netty.streambase2; 2 | 3 | import java.util.List; 4 | 5 | import io.netty.buffer.ByteBuf; 6 | import io.netty.channel.ChannelHandlerContext; 7 | import io.netty.handler.codec.ByteToMessageDecoder; 8 | 9 | public class TimeDecoder extends ByteToMessageDecoder { // (1) 10 | 11 | @Override 12 | protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out) { // (2) 13 | if (in.readableBytes() < 4) { 14 | return; // (3) 15 | } 16 | 17 | out.add(in.readBytes(4)); // (4) 18 | } 19 | } -------------------------------------------------------------------------------- /src/com/yiibai/netty/streambase2/TimeServer.java: -------------------------------------------------------------------------------- 1 | package com.yiibai.netty.streambase2; 2 | 3 | import io.netty.bootstrap.ServerBootstrap; 4 | 5 | import io.netty.channel.ChannelFuture; 6 | import io.netty.channel.ChannelInitializer; 7 | import io.netty.channel.ChannelOption; 8 | import io.netty.channel.EventLoopGroup; 9 | import io.netty.channel.nio.NioEventLoopGroup; 10 | import io.netty.channel.socket.SocketChannel; 11 | import io.netty.channel.socket.nio.NioServerSocketChannel; 12 | 13 | /** 14 | * 时间服务器 15 | */ 16 | public class TimeServer { 17 | 18 | private int port; 19 | 20 | public TimeServer(int port) { 21 | this.port = port; 22 | } 23 | 24 | public void run() throws Exception { 25 | EventLoopGroup bossGroup = new NioEventLoopGroup(); // (1) 26 | EventLoopGroup workerGroup = new NioEventLoopGroup(); 27 | try { 28 | ServerBootstrap b = new ServerBootstrap(); // (2) 29 | b.group(bossGroup, workerGroup) 30 | .channel(NioServerSocketChannel.class) // (3) 31 | .childHandler(new ChannelInitializer() { // (4) 32 | @Override 33 | public void initChannel(SocketChannel ch) throws Exception { 34 | ch.pipeline().addLast(new TimeServerHandler()); 35 | } 36 | }) 37 | .option(ChannelOption.SO_BACKLOG, 128) // (5) 38 | .childOption(ChannelOption.SO_KEEPALIVE, true); // (6) 39 | 40 | // 绑定端口,开始接收进来的连接 41 | ChannelFuture f = b.bind(port).sync(); // (7) 42 | 43 | // 等待服务器 socket 关闭 。 44 | // 在这个例子中,这不会发生,但你可以优雅地关闭你的服务器。 45 | f.channel().closeFuture().sync(); 46 | } finally { 47 | workerGroup.shutdownGracefully(); 48 | bossGroup.shutdownGracefully(); 49 | } 50 | } 51 | 52 | public static void main(String[] args) throws Exception { 53 | int port; 54 | if (args.length > 0) { 55 | port = Integer.parseInt(args[0]); 56 | } else { 57 | port = 8080; 58 | } 59 | new TimeServer(port).run(); 60 | } 61 | } -------------------------------------------------------------------------------- /src/com/yiibai/netty/streambase2/TimeServerHandler.java: -------------------------------------------------------------------------------- 1 | package com.yiibai.netty.streambase2; 2 | import io.netty.buffer.ByteBuf; 3 | import io.netty.channel.ChannelFuture; 4 | import io.netty.channel.ChannelFutureListener; 5 | import io.netty.channel.ChannelHandlerContext; 6 | import io.netty.channel.ChannelInboundHandlerAdapter; 7 | 8 | public class TimeServerHandler extends ChannelInboundHandlerAdapter { 9 | 10 | @Override 11 | public void channelActive(final ChannelHandlerContext ctx) { // (1) 12 | final ByteBuf time = ctx.alloc().buffer(4); // (2) 13 | time.writeInt((int) (System.currentTimeMillis() / 1000L + 2208988800L)); 14 | 15 | final ChannelFuture f = ctx.writeAndFlush(time); // (3) 16 | f.addListener(new ChannelFutureListener() { 17 | @Override 18 | public void operationComplete(ChannelFuture future) { 19 | assert f == future; 20 | ctx.close(); 21 | } 22 | }); // (4) 23 | } 24 | 25 | @Override 26 | public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { 27 | cause.printStackTrace(); 28 | ctx.close(); 29 | } 30 | } -------------------------------------------------------------------------------- /src/com/yiibai/netty/time/TimeClient.java: -------------------------------------------------------------------------------- 1 | 2 | package com.yiibai.netty.time; 3 | import io.netty.bootstrap.Bootstrap; 4 | import io.netty.channel.ChannelFuture; 5 | import io.netty.channel.ChannelInitializer; 6 | import io.netty.channel.ChannelOption; 7 | import io.netty.channel.EventLoopGroup; 8 | import io.netty.channel.nio.NioEventLoopGroup; 9 | import io.netty.channel.socket.SocketChannel; 10 | import io.netty.channel.socket.nio.NioSocketChannel; 11 | 12 | public class TimeClient { 13 | 14 | public static void main(String[] args) throws Exception { 15 | 16 | String host = "127.0.0.1";// args[0]; 17 | int port = 8080;//Integer.parseInt(args[1]); 18 | EventLoopGroup workerGroup = new NioEventLoopGroup(); 19 | 20 | try { 21 | Bootstrap b = new Bootstrap(); // (1) 22 | b.group(workerGroup); // (2) 23 | b.channel(NioSocketChannel.class); // (3) 24 | b.option(ChannelOption.SO_KEEPALIVE, true); // (4) 25 | b.handler(new ChannelInitializer() { 26 | @Override 27 | public void initChannel(SocketChannel ch) throws Exception { 28 | ch.pipeline().addLast(new TimeClientHandler()); 29 | } 30 | }); 31 | 32 | // 启动客户端 33 | ChannelFuture f = b.connect(host, port).sync(); // (5) 34 | 35 | // 等待连接关闭 36 | f.channel().closeFuture().sync(); 37 | } finally { 38 | workerGroup.shutdownGracefully(); 39 | } 40 | } 41 | } -------------------------------------------------------------------------------- /src/com/yiibai/netty/time/TimeClientHandler.java: -------------------------------------------------------------------------------- 1 | package com.yiibai.netty.time; 2 | 3 | import java.text.SimpleDateFormat; 4 | import java.util.Date; 5 | 6 | import io.netty.buffer.ByteBuf; 7 | import io.netty.channel.ChannelHandlerContext; 8 | import io.netty.channel.ChannelInboundHandlerAdapter; 9 | 10 | public class TimeClientHandler extends ChannelInboundHandlerAdapter { 11 | 12 | @Override 13 | public void channelRead(ChannelHandlerContext ctx, Object msg) { 14 | ByteBuf m = (ByteBuf) msg; // (1) 15 | try { 16 | long currentTimeMillis = (m.readUnsignedInt() - 2208988800L) * 1000L; 17 | Date currentTime = new Date(currentTimeMillis); 18 | System.out.println("Default Date Format:" + currentTime.toString()); 19 | 20 | SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 21 | String dateString = formatter.format(currentTime); 22 | // 转换一下成中国人的时间格式 23 | System.out.println("Date Format:" + dateString); 24 | 25 | ctx.close(); 26 | } finally { 27 | m.release(); 28 | } 29 | } 30 | 31 | @Override 32 | public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { 33 | cause.printStackTrace(); 34 | ctx.close(); 35 | } 36 | } -------------------------------------------------------------------------------- /src/com/yiibai/netty/time/TimeServer.java: -------------------------------------------------------------------------------- 1 | package com.yiibai.netty.time; 2 | 3 | import io.netty.bootstrap.ServerBootstrap; 4 | 5 | import io.netty.channel.ChannelFuture; 6 | import io.netty.channel.ChannelInitializer; 7 | import io.netty.channel.ChannelOption; 8 | import io.netty.channel.EventLoopGroup; 9 | import io.netty.channel.nio.NioEventLoopGroup; 10 | import io.netty.channel.socket.SocketChannel; 11 | import io.netty.channel.socket.nio.NioServerSocketChannel; 12 | 13 | /** 14 | * 时间服务器 15 | */ 16 | public class TimeServer { 17 | 18 | private int port; 19 | 20 | public TimeServer(int port) { 21 | this.port = port; 22 | } 23 | 24 | public void run() throws Exception { 25 | EventLoopGroup bossGroup = new NioEventLoopGroup(); // (1) 26 | EventLoopGroup workerGroup = new NioEventLoopGroup(); 27 | try { 28 | ServerBootstrap b = new ServerBootstrap(); // (2) 29 | b.group(bossGroup, workerGroup) 30 | .channel(NioServerSocketChannel.class) // (3) 31 | .childHandler(new ChannelInitializer() { // (4) 32 | @Override 33 | public void initChannel(SocketChannel ch) throws Exception { 34 | ch.pipeline().addLast(new TimeServerHandler()); 35 | } 36 | }) 37 | .option(ChannelOption.SO_BACKLOG, 128) // (5) 38 | .childOption(ChannelOption.SO_KEEPALIVE, true); // (6) 39 | 40 | // 绑定端口,开始接收进来的连接 41 | ChannelFuture f = b.bind(port).sync(); // (7) 42 | 43 | // 等待服务器 socket 关闭 。 44 | // 在这个例子中,这不会发生,但你可以优雅地关闭你的服务器。 45 | f.channel().closeFuture().sync(); 46 | } finally { 47 | workerGroup.shutdownGracefully(); 48 | bossGroup.shutdownGracefully(); 49 | } 50 | } 51 | 52 | public static void main(String[] args) throws Exception { 53 | int port; 54 | if (args.length > 0) { 55 | port = Integer.parseInt(args[0]); 56 | } else { 57 | port = 8080; 58 | } 59 | new TimeServer(port).run(); 60 | } 61 | } -------------------------------------------------------------------------------- /src/com/yiibai/netty/time/TimeServerHandler.java: -------------------------------------------------------------------------------- 1 | package com.yiibai.netty.time; 2 | import io.netty.buffer.ByteBuf; 3 | import io.netty.channel.ChannelFuture; 4 | import io.netty.channel.ChannelFutureListener; 5 | import io.netty.channel.ChannelHandlerContext; 6 | import io.netty.channel.ChannelInboundHandlerAdapter; 7 | 8 | public class TimeServerHandler extends ChannelInboundHandlerAdapter { 9 | 10 | @Override 11 | public void channelActive(final ChannelHandlerContext ctx) { // (1) 12 | final ByteBuf time = ctx.alloc().buffer(4); // (2) 13 | time.writeInt((int) (System.currentTimeMillis() / 1000L + 2208988800L)); 14 | 15 | final ChannelFuture f = ctx.writeAndFlush(time); // (3) 16 | f.addListener(new ChannelFutureListener() { 17 | @Override 18 | public void operationComplete(ChannelFuture future) { 19 | assert f == future; 20 | ctx.close(); 21 | } 22 | }); // (4) 23 | } 24 | 25 | @Override 26 | public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { 27 | cause.printStackTrace(); 28 | ctx.close(); 29 | } 30 | } --------------------------------------------------------------------------------