对Netty的理解+网络调试助手
最近学习了使用netty进行网络通信,对数据帧进行封装打包等,记录一下遇到的问题。网上很官方的描述就不再描述啦。其次,这个笔记是根据近期实现的项目而做的,因此比较偏向于与实物之间的通信协议问题。
一、Netty是什么
Netty是一款基于NIO(Nonblocking I/O,非阻塞IO)开发的网络通信框架。
二、Netty作为服务器端的整体架构
出去一个监听器去调用服务之外,主要分为以下4个部分:
①NettyServer (or Client )进行服务的启动,在这里可以定义自己是服务端还是客户端,同时定义channel通道进行使用;
②Decoder 使用①中的channel通道拿到收取的报文,对接受到的数据帧进行解码拿到自己想要的信息;
③Encoder 同②所述,将想要发送给远程客户端的消息体封装成报文并放入channel通道进行发送;
④Handler 这里主要进行一些逻辑处理,例如通道刚刚激活后,要进行什么事务以及读通道中的消息;
1、 NettyServer
首先,来一段作为服务器端的代码(由于是新手,几乎每一句都去搜了是什么意思,写在了注释里,方便以后复习查看):
一些参数查看了这个博客:链接: link.
//NettyServer.java
private static ServerBootstrap serverBootstrap;
public static void initNetty(String ip, Integer port,Integer IDLETIME_READER,Integer IDLETIME_WRITER,Integer IDLETIME_ALL) throws InterruptedException {
//创建一个ServerBootstrap实例,是Netty的启动辅助类,提供了一些列的方法用于设置服务器的参数
serverBootstrap = new ServerBootstrap();
//设置线程池
EventLoopGroup boss = new NioEventLoopGroup();//用于服务器端接收客户端的连接
EventLoopGroup worker = new NioEventLoopGroup();//用于处理网络事件
serverBootstrap.group(boss, worker)
.channel(NioServerSocketChannel.class)//设置绑定服务器端的channel(NioServerSocketChannel)
.option(ChannelOption.SO_BACKLOG, 2048)//BACKLOG用于构造服务端套接字ServerSocket对象,标识当服务器请求处理线程全满时,用于临时存放已完成三次握手的请求的队列的最大长度。如果未设置或所设置的值小于1,Java将使用默认值50
.option(ChannelOption.RCVBUF_ALLOCATOR,new AdaptiveRecvByteBufAllocator(512, 1024, 65536))
.option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT)
.option(ChannelOption.RCVBUF_ALLOCATOR, AdaptiveRecvByteBufAllocator.DEFAULT)//以上三行设置接收缓冲区,这里感觉比较迷糊看不懂,以后继续看
.childOption(ChannelOption.SO_KEEPALIVE, true)//是否启用心跳保活机制。在双方TCP套接字建立连接后(即都进入ESTABLISHED状态)并且在两个小时左右上层没有任何数据传输的情况下,这套机制才会被激活
.childOption(ChannelOption.TCP_NODELAY, true)//用于启用或关于Nagle算法(尽可能发送大块数据,避免网络中充斥着许多小数据块)。如果要求高实时性,有数据发送时就马上发送,就将该选项设置为true关闭Nagle算法;如果要减少发送次数减少网络交互,就设置为false等累积一定大小后再发送。默认为false
.childHandler(new ChannelInitializer<SocketChannel>() {
//定义ChannelInitializer的匿名类对象,并作为childHandler方法的参数,将其赋值给childHandler
@Override
protected void initChannel(SocketChannel channel) throws Exception {
channel.pipeline()
.addLast("idleStateHandler", new IdleStateHandler(IDLETIME_READER, IDLETIME_WRITER, IDLETIME_ALL, TimeUnit.SECONDS))//服务端添加IdleStateHandler心跳检测处理器,READER是读超时时间,WRITER是写超时时间,ALL是写+读总共的(好像是),最后是前面三个时间的单位是SECONDS(秒)【我就因为没有修改单位傻傻的盯着表等了好久也没有断开连接55】一旦超时触发这个事件,就会进入到Handler的userEventTriggered中,我们可以自己定义相关处理
.addLast("decoder", new ServerDecoder())
.addLast("channelHandler"<