Netty 基本介绍与核心组件(EventLoop、ChannelPipeline、ChannelHandler)

TCP 基础

TCP是一种面向连接的、可靠的、基于字节流传输层通信协议

连接:连接就是双方遵循约定,client、server相互了解,知道对方的信息并且保留地址、buffer、状态等信息的过程叫做连接

字节流:流是一方发,另一方只需要读,收到的是一串01数字;而报文是发送的一个字符串或其它一组数据,组合在一个包中进行发送

滑动窗口:每次发送包的数量,当这一批(窗口内)的包发送完成,移动到下一个窗口,删除已发送的包

三次握手:client向server发送请求,server响应ack,然后client收到后响应ack给server。只有经过三次,双方才能确定对方是没问题的,我发的包对方能收到且能返回ack

TCP如何保证接收到字节流间的顺序?
每一个包都有序号,对方将收到的一个包放在buffer;比如收到了第4个包则返回ack 4;在buffer满后再按照包顺序写入


Socket 基础

在这里插入图片描述
socket就是创建一个socket对象
bind表示绑定到一个端口,基于这个端口传输字节流
listen表示将socket置于侦听状态
accept表示接受一个连接(会去底层去看哪些连接三次握手成功了的连接),如果没有连接就会一直阻塞在这里

React模式

在使用Socket编码中,所有的代码都冗余在一起,更像是面向过程的,而React就是将这些逻辑进行抽象、解耦的模式
在这里插入图片描述

将所有职责分开,有人专门做accept、有人read、write数据,它们都是由一个handler类来处理,不同事件触发不同的方法,比如

handler.onAccept();
handler.onRead((SocketChannel) key.channel());



Netty

Netty是一个NIO客户端服务器框架,支持快速和简单网络应用程序的开发,如协议服务器和客户端。

核心组件

EventLoop:事件轮询,对所有的事件进行轮询检查

在这里插入图片描述

ChannelPipeline:流水线,中间所有的handler(都被ctx包裹着)都有机会处理数据,一个handler做完会给(fire)下一个handler
在这里插入图片描述

ch.pipeline().addLast(new LineBasedFrameDecoder(80,false,false));
ch.pipeline().addLast(new StringDecoder());
ch.pipeline().addLast(new EchoHandler());

ChannelHandler:一些channel逻辑或数据处理的handler

ChannelPipeline&ChannelHandler关系?
在这里插入图片描述

如何对字节流拆包?

拆包:对一连串的流进行拆解

拆包方案:

  1. 使用分隔符:数据中可能会有此分隔符
  2. 在头部增加长度:对于一些不是自己的包,无法识别
  3. 业界正确做法magic(魔数也就是标识符)+数据长度+数据,如下图所示

在这里插入图片描述
数据流就是由三部分组成,基本过程如下:

  1. 在接收方会根据header来识别是否是需要解析的流

  2. 根据length长度获取指定长度的数据

  3. 让后将收到的ByteBuf进行处理转换,比如转换成string
    在Netty中提供了LineBasedFrameDecoder类来进行处理基于长度的帧的解码器,可动灵活配置解码方式

    // 基于长度的帧的解码器,可动灵活配置解码方式
    // maxFrameLength 最大的帧长度1024
    // lengthFieldOffset length字段的偏移量(length在帧的位置)0
    // lengthFieldLength length字段的长度2
    // lengthAdjustment 帧的length是否包含length字段,不包含
    // initialBytesToStrip 从解码帧中裁剪出的字节数(返回的Bytes是否包含length字段或其它其它字段)2
    new LengthFieldBasedFrameDecoder(1024, 0, 2, 0, 2);
    

思考

  • 阻塞、非阻塞、异步、同步区别?
    阻塞/非阻塞是api级别的,比如lock()是阻塞的,tryLock()是非阻塞的
    同步/异步其实就是主动调用和被动调用的区别,同步就是从头到尾,异步就是就是之后会被调用,比如ajax

  • Netty有什么缺点吗?
    比如ChannelPipeline+ChannelHandler的组合,使得所有逻辑割裂,逻辑散落在各个handler类中,且handler之间有先后顺序、是否传递到下一个handler等,如果不进行调试难以阅读处理过程

  • Netty和Tomcat的区别?
    netty是基于TCP,可以自定义一些特殊协议,可以成为一个tomcat也可以做HTTP协议
    tomcat是应用层协议,基于servlet模式,是一个http的模型,比如getHeader()、getBody()都是http的概念

扩展

零拷贝:kernal内部有一套写入或发送的api,在java中也有byte数组存在内存中,写入到Socket的时候,需要将内存数据拷贝到kernal态侧,然后再写入到Socket中
而零拷贝是指将kerna一部分数据l映射出来,而不需要从用户态和kernal态处进行拷贝,在kernal态中直接发送数据到socket

epoll(来源百度百科):epoll是Linux下多路复用IO接口select/poll的增强版本,它能显著提高程序在大量并发连接中只有少量活跃的情况下的系统CPU利用率。另一点原因就是获取事件的时候,它无须遍历整个被侦听的描述符集,只要遍历那些被内核IO事件异步唤醒而加入Ready队列的描述符集合就行了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我思知我在

原创不易,多多一键三连

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值