自己学习用netty之前有很多的疑惑,这里先把自己的疑惑与答案写出来,希望可以帮到有同样疑惑的朋友。
问题:netty版本的选择,3,4,5。
答案:3和4的改动挺大,但是4和5的不大,现在官方给的版本是4,本来是有5的,结果下架了,但是可以在很多maven库中找到5。所有人都希望自己所学的内容生命周期长点,并不想刚学完就会废弃掉。我推荐的版本是4。跟着官方走。
问题:netty的书的选择
答案:我看了几本,最后认为《netty权威指南》不错,他的知识点比较全面,可能入手去读得有一定的基础,否则在读IO模型的时候很多人就糊涂了。这本书是基于5讲的,我还是推荐,主要4和5变动不大。变动的部分还是可以接受的。
问题:学netty一定要会用java IO ,NIO吗
答案:netty作为一个框架,就是屏蔽这些复杂操作的,所以是不需要特别精通java的部分,而且netty提供了自己的包装类。如果是入手学习这个框架,我认为是可以不用的,但是基本的socket编程基础是需要的。主要是会一定socket基础,可以有一个良好的逻辑思维,要不你都不知道框架是干啥的。后面想继续阅读源码,那就需要把这些知识都补充起来。
问题:netty的优势
大家都知道socket传输和语言无关,和机器无关(当然,大端机器和小端机器读取的结果不一样需要特殊处理一下,但是所有机器都可以接收)。所以我们的程序不写客户端,用系统自带的telnet来做客户端访问。我们只写服务端。
写过socket程序都知道,服务端的socket是有几个通用操作的,例如accept,read,write。我们这次也主要围绕这几个来对比的看。
public void bind(int port) {
EventLoopGroup boss = new NioEventLoopGroup();
EventLoopGroup worker = new NioEventLoopGroup();
try {
ServerBootstrap server = new ServerBootstrap();
server.group(boss, worker).channel(NioServerSocketChannel.class)
.childHandler(new ChannelInitializer<Channel>() {
@Override
protected void initChannel(Channel ch) throws Exception {
ch.pipeline().addLast(new MessageHandler());
}
});
ChannelFuture sync = server.bind(port).sync();
sync.channel().closeFuture().sync();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
boss.shutdownGracefully();
worker.shutdownGracefully();
}
}
上面这段代码为什么要这么写,建议大家先不考虑这个问题,就先这么写。作为一个server端的编写,我们主要在乎的是端口。无论什么框架,什么模型,socket的主要都是port,唯一我们需要写的业务就是MessageHandler
public class MessageHandler extends ChannelInboundHandlerAdapter{
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
ByteBuf buf =(ByteBuf)msg;
int readableBytes = buf.readableBytes();
byte[] bytes =new byte[readableBytes];
buf.readBytes(bytes);
System.out.println(new String(bytes));
}
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
System.out.println("connection");
}
}
这里我重新了两个方法,一个是channelRead,一个是channelActive。很明显的对应我上面说的accpet和read。这里很多人问为什么msg一定是用byte来接收呢。这个其实和协议有关,不过我建议大家先想想普通socket编程你获取的不是inputstream和outputstream吗,他们本身就是处理字节流的。所以这里也是一样的。处理字节流。
很多人学socket的时候都是自己写客户端,自己写服务端。所以大概介绍一下telnet的使用。
telnet ip port
ctrl + ] 进入命令发消息模式
send hello 这样就会把hello发送出去
大家通过上面的介绍一定可以完成程序,并且可以收到telnet发送的结果,只是感觉用了半天,其实啥也不知道,因为netty的事情我一句没说。这也是我最开始学习框架遇到的问题,内心其实是不满足会用的层次的,总想知道原理,为什么这么用,最后花掉了大部分的时间进去,结果是原理是不错了,可是框架本身用法上没有怎么感受,所以现在我想大家的思维可以换一换,更关注业务,先会用,再说为啥用。