Practical Netty (1) 基於Netty實現的一個rdate server例項
Practical Netty (1) 基於Netty實現的一個rdate server例項
- 作者:鍾超(Poechant)
- 郵箱:zhongchao.ustc#gmail.com
- 部落格:blog.csdn.net/poechant
- 微博:weibo.com/lauginhom
Netty 是一個高效的 Java 網路框架,簡單的介紹可參見《Java NIO框架Mina、Netty、Grizzly介紹與對比》一文。對於不熟悉 NIO 的 Java 開發者,Netty 的使用需要一小段的時間來熟悉。當然 Netty 已經更好地封裝了 NIO,所以您大可不必先去了解完 NIO,再來了解 Netty。
下面是一個簡單的 rdate server 例項,大部分程式碼參考 Netty Official Examples。什麼是 rdate?如果你是 *nix 使用者的話,就一定知道:
rdate is a command to set the system's date from a remote host.
具體如下:
rdate displays and sets the local date and time from the host name or
address given as the argument. The time source may be an RFC 868 TCP
protocol server, which is usually implemented as a built-in service of
inetd(8), or an RFC 2030 protocol SNTP/NTP server. By default, rdate
uses the RFC 868 TCP protocol.
RdateServer.java
package com.sinosuperman.test.netty;
import java.net.InetSocketAddress;
import java.util.concurrent.Executors;
import org.jboss.netty.bootstrap.ServerBootstrap;
import org.jboss.netty.channel.ChannelFactory;
import org.jboss.netty.channel.ChannelPipeline;
import org.jboss.netty.channel.ChannelPipelineFactory;
import org.jboss.netty.channel.Channels;
import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;
public class RdateServer {
private static int port = 28080;
public static void main(String[] args) {
// ChannelFactory is a factory which creates and manages Channels and
// its related resources.
ChannelFactory factory =
new NioServerSocketChannelFactory(
Executors.newCachedThreadPool(), // boss executor
Executors.newCachedThreadPool()); // worker executor
// ServerBootstrap is a helper class that sets up a server. You can set
// up the server using a Channel directly. However, please note that
// this is a tedious process and you do not need to do that in most
// cases.
ServerBootstrap bootstrap = new ServerBootstrap(factory);
bootstrap.setPipelineFactory(new ChannelPipelineFactory() {
@Override
public ChannelPipeline getPipeline() throws Exception {
return Channels.pipeline(new RdateServerHandler());
}
});
bootstrap.setOption("child.tcpNoDelay", true);
bootstrap.setOption("child.keepAlive", true);
bootstrap.bind(new InetSocketAddress(port));
}
}
RdateServerHandler.java
下面比較有意思的就是和 NIO 中的 ByteBuffer 類似的 ChannelBuffer,很好用。ChannelFuture 也是 Netty 中經常使用到的。
package com.sinosuperman.test.netty;
import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.buffer.ChannelBuffers;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelFuture;
import org.jboss.netty.channel.ChannelFutureListener;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.channel.ChannelStateEvent;
import org.jboss.netty.channel.ExceptionEvent;
import org.jboss.netty.channel.SimpleChannelHandler;
public class RdateServerHandler extends SimpleChannelHandler {
@Override
public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e)
throws Exception {
Channel ch = e.getChannel();
// To send a new message, we need to allocate a new buffer which will
// contain the message. We are going to write a 32-bit integer, and
// therefore we need a ChannelBuffer whose capacity is 4 bytes. The
// ChannelBuffers helper class is used to allocate a new buffer. Besides
// the buffer method, ChannelBuffers provides a lot of useful methods
// related to the ChannelBuffer. For more information, please refer to
// the API reference.
ChannelBuffer time = ChannelBuffers.buffer(4);
time.writeInt((int) (System.currentTimeMillis() / 1000L + 2208988800L));
ChannelFuture f = ch.write(time);
f.addListener(ChannelFutureListener.CLOSE);
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e)
throws Exception {
e.getCause().printStackTrace();
Channel ch = e.getChannel();
ch.close();
}
}
這裡比較重要的是時間的計算公式:
System.currentTimeMillis() / 1000L + 2208988800L
具體不細說了,算是一個小常識吧。
客戶端測試
客戶端就是 Linux 提供的 rdate 命令,如下方式測試:
$ rdate -o <rdate_server_port> -p <rdate_server_ip>
這裡預設使用的是 28080。
$rdate -o 28080 -p 127.0.0.1
Fri Dec 28 14:21:05 CST 2012
-
轉載請註明來自鍾超(Poechant)的 CSDN 部落格:http://blog.csdn.net/poechant,作者微博:http://weibo.com/lauginhom
-
相關文章
- 基於SpringBoot+Netty實現一個自己的推送服務系統Spring BootNetty
- 基於大量圖片與例項深度解析Netty中的核心元件Netty元件
- 造個輪子之基於 Netty 實現自己的 RPC 框架NettyRPC框架
- 開源一個自用的Android IM庫,基於Netty+TCP+Protobuf實現。AndroidNettyTCP
- 手把手教你基於Netty實現一個基礎的RPC框架(通俗易懂)NettyRPC框架
- 基於Netty自己動手實現Web框架NettyWeb框架
- Netty實現的一個非同步Socket程式碼Netty非同步
- 自己用 Netty 實現一個簡單的 RPCNettyRPC
- 基於Netty的Android系統IM簡單實現原理NettyAndroid
- Netty 框架學習 —— 基於 Netty 的 HTTP/HTTPS 應用程式Netty框架HTTP
- netty系列之:Bootstrap,ServerBootstrap和netty中的實現NettybootServer
- netty系列之:EventExecutor,EventExecutorGroup和netty中的實現Netty
- netty系列之:channel,ServerChannel和netty中的實現NettyServer
- netty實戰之一 認識nettyNetty
- 從零手寫實現 nginx-03-nginx 基於 Netty 實現NginxNetty
- 基於netty的聊天室Netty
- 基於Netty實現Redis協議的編碼解碼器NettyRedis協議
- 手寫一個類SpringBoot的HTTP框架:幾十行程式碼基於Netty搭建一個 HTTP ServerSpring BootHTTP框架行程NettyServer
- Netty1:初識NettyNetty
- netty系列之:EventLoop,EventLoopGroup和netty的預設實現NettyOOP
- 基於Netty實現海量接入的推送服務技術要點Netty
- Netty 框架學習 —— 第一個 Netty 應用Netty框架
- 基於Java NIO 寫的一個簡單版 Netty 服務端JavaNetty服務端
- netty系列之:netty實現http2中的流控制NettyHTTP
- Netty實現Web SocketNettyWeb
- 大廚小鮮——基於Netty自己動手實現RPC框架NettyRPC框架
- 使用Netty和動態代理實現一個簡單的RPCNettyRPC
- 基於netty手寫RPC框架NettyRPC框架
- 基於Netty4手把手實現一個帶註冊中心和註解的Dubbo框架Netty框架
- Netty原始碼解析8-ChannelHandler例項之CodecHandlerNetty原始碼
- 聊聊 Netty 那些事兒之 Reactor 在 Netty 中的實現(建立篇)NettyReact
- netty系列之:使用netty實現支援http2的伺服器NettyHTTP伺服器
- netty 實現簡單的rpc呼叫NettyRPC
- Android 基於Netty的訊息推送方案之Hello World(一)AndroidNetty
- Netty基礎招式——ChannelHandler的最佳實踐Netty
- Netty原始碼分析(一):Netty總覽Netty原始碼
- Netty 原始碼分析系列(一)Netty 概述Netty原始碼
- 《Netty實戰》-學習筆記1Netty筆記
- 跟著原始碼學IM(九):基於Netty實現一套分散式IM系統原始碼Netty分散式