根据 netty 4.1 如下官方文档:
练习如下官方示例程序:
另外,又扩展了两个示例:
用于学习 netty 的功能和基本使用方法。
下图来自netty官网,包含netty的所有组件, 同时也诠释了netty的功能之强大:
Client连上Server后,Server忽略所有Client发送过来的消息。
运行方法如下:
在Window上可以使用如下telnet命令进行测试:
telnet localhost 8009
Client 中每输入一个字符,Server 就立即发送相同的字符给Client。
运行方法如下:
在Window上可以使用如下telnet命令进行测试:
telnet localhost 8005
对应 Writing a Time Server 和 Writing a Time Client 。
当Client连上Server时,Server把系统当前时间发送给Client。
运行方法如下:
启动 TimeServer。
在Windows可以启动 TimeClient 进行测试;在Linux上可以使用如下telnet命令进行测试:
rdate -o 8005 -p localhost
对应 Dealing with a Stream-based Transport > The First Solution ,基于 time 的示例,演示netty解决TCP粘包/半包问题比较简单粗糙的方案:在 TimeClientHandler 的两个 life cycle listener methods: handlerAdded() and handlerRemoved() 中显式控制只读取4个byte。
当Client连上Server时,Server把系统当前时间发送给Client。
运行方法如下:
启动 TimeServer。
在Windows可以启动 TimeClient 进行测试。
对应 Dealing with a Stream-based Transport > The Second Solution ,基于 stream 的示例,演示netty解决TCP粘包/半包问题、相对优雅些的方案:
添加另一个TimeClientHandler: TimeDecoder,TimeDecoder继承自 ByteToMessageDecoder,而ByteToMessageDecoder继承自ChannelInboundHandlerAdapter,用于读取4个byte。
将TimeDecoder添加至Client的ChannelPipeline:
b.handler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline p = ch.pipeline();
if (sslCtx != null) {
p.addLast(sslCtx.newHandler(ch.alloc(), HOST, PORT));
}
p.addLast(new LoggingHandler(LogLevel.INFO));
p.addLast(new TimeDecoder(), new TimeClientHandler());
}
});
TimeDecoder的类图如下:
当Client连上Server时,Server把系统当前时间发送给Client。
运行方法如下:
启动 TimeServer。
在Windows可以启动 TimeClient 进行测试。
对应 Speaking in POJO instead of ByteBuf ,基于 stream2 的示例,演示netty解决TCP粘包/半包问题的最优雅方案:
添加UnixTime,它用于封装时间,即server和client两端交流的data。
添加TimeServerHandler: TimeEncoder;TimeDecoder继承自 MessageToByteEncoder,而MessageToByteEncoder继承自ChannelInboundHandlerAdapter,用于编码UnixTime。
将TimeEncoder添加至Server的ChannelPipeline:
b.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline p = ch.pipeline();
if (sslCtx != null) {
p.addLast(sslCtx.newHandler(ch.alloc()));
}
p.addLast(new TimeEncoder(), serverHandler);
}
});
添加TimeClientHandler: TimeDecoder;TimeDecoder继承自 ByteToMessageDecoder,而ByteToMessageDecoder继承自ChannelOutboundHandlerAdapter,用于解码UnixTime。
将TimeDecoder添加至Client的ChannelPipeline:
b.handler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline p = ch.pipeline();
if (sslCtx != null) {
p.addLast(sslCtx.newHandler(ch.alloc(), HOST, PORT));
}
p.addLast(new LoggingHandler(LogLevel.INFO));
p.addLast(new TimeDecoder(), new TimeClientHandler());
}
});
TimeEncoder和TimeDecoder的类图如下:
当Client连上Server时,Server把系统当前时间发送给Client。
运行方法如下:
参照 Netty Github 4.1 Branch 的 localecho example。
运行方法如下:
参照 Netty Project > Understanding Netty using simple real-world example of Chat server client > Good for beginners 写了一个简单的chat小程序。
运行方法如下: