快速入门netty

        如果说学过网络编程,其实netty入门使用并不难,我本身学过一些netty的使用,但是久不使用,有些忘记,故做此记录以待以后复习。

pipeline:流水线,可以视为buffer里的数据会经过好几个加工过程,每个过程使用一个handler去加工,类似于做一道菜。

write:把数据往文件描述符的发送缓冲区填充,但是没有马上发送。

writeAndFlush:把数据往socket的发送缓冲区填充,并且清空缓冲区。

        connect方法是异步非阻塞的,即主线程发起调用,真正执行connect的是nio线程,所以要加sync,需要有阻塞的获取channel。因为connect调用不能马上连接得上,如果是无阻塞的,很可能无法获取channel.带有promise,future基本是异步非阻塞的。sync的作用:阻塞当前线程,直到nio线程连接建立完毕。

        netty中很多方法的执行是异步的,比如close,connect。方法执行不在同一个线程中,所有为了实现同步,要使用sync,比如说要在channel.close后清空所以资源,就要使用到closeFuture。

 head->h1->tail,handler主要有两种,inbound的handler,主要在读取数据的时候对数据进行加工。outbound,主要在发送数据的时候对数据进行加工。如下程序在读取数据的时候会打印1.outbound的handler只有向channel写入数据的时候才会触发。msg其实就是数据buffer,每个handler在处理过数据之后,可以把当前msg传给下一个handler。

         bytebuf:作为数据缓冲区的存在,学过网络编程的同学应该都只是,在多线程的网络编程中,一个eventloop事件循环可以处理多个连接,每个连接对应一个channel,每个channel对应着两个buf:读缓冲区和写缓冲区,在解码的时候即从socket中读取的数据先存入buffer,直到buffer里面有一条完整的记录,发送信息的时候,需要写缓存区,即把写缓冲区里面的数据往socket的发送缓冲区中搬运,由于socket的发送缓冲区大小有限制,比如说socket的发送缓冲区大小是200字节,而一条报文长度为300字节,那么剩下的100字节就应该先存放在写缓冲区,等socket发送缓冲区空了之后再把剩余的100字节放入socket发送缓冲区。

绿色箭头:读指针,即要读取数据要从读指针的下标开始

蓝色箭头:写指针,即写数据要从写指针下标开始。

capacity:容量

max capacity:最大容量

         netty中零拷贝和操作系统层面的零拷贝并不不一致,在网络编程中,读取数据的流向是网卡->socket缓冲区->用户缓冲区。要经过多次内存搬运,零拷贝的一种实现是mmap,mmap主要实现方式是将内核读缓冲区的地址和用户缓冲区的地址进行映射,内核缓冲区和应用缓冲区共享,从而减少了从读缓冲区到用户缓冲区的一次CPU拷贝。

        netty中的零拷贝也是为了减少数据复制,slice和原始bytebuf使用的同样的物理内存。

        粘包半包:其实这是一个伪概念,因为tcp是面向字节流的编程,消息无边界。包是用户层定义的,而非在传输层,tcp只负责用户发送啥,接收端就接到啥,数据的编码解码应该由用户实现.发生粘包的原因也很简单,比方说socket缓冲区的大小是300,用户数据大小是200.用户发送数据的时候,就是由一条完整的数据和第二条数据的前100字节,这就产生了粘包,所以这正是为什么需要用户缓冲区的原因,用于数据的编码的解码。

        解决方案也显而易见:netty提供了编码器和解码器。

FixedLengthFrameDecoder:定长解码器,加入一个包定长10字节,服务器一次收到100字节,解码器把每10字节视为一个包,可以解析出10个包。

行解码器:遇到“/n”,"/rn"等分隔符,视为一个包。

SimpleChannelInboundHandler<T>:指定特定类型数据T感兴趣的入栈处理器。

自定义协议:

 

 msg是实现了序列化,反序列化接口的对象,buf out是发送缓冲区,自定义协议的过程如下:

1写入魔数

2写入版本号

3写入指令类型

4把对象序列化,得到序列化数组的长度,写入长度。

5写入对象序列化数值

反序列化就是序列化的逆过程,最后要使用out.add,因为可能解析出多条消息,每解析出一条消息就加入list当中,供下一站的handler使用。

 事实上为了解决粘包,半包问题,还需要加入帧解码器,举个例子,半包现象,故意把buf分为s1和s2,就出现了半包问题,在decode的时候,半包会出现反序列失败。加入帧解码器,当发现数据不足一个包的时候,会等待,等待完整数据的到来。

        

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值