Netty 网络编程

Netty 网络编程

一、网络编程基础

Netty在网络编程中,稍微偏底层,java开发主要在http层,Netty主要是在传输层。Netty为上层框架提供服务。Doubble 内部通信协议用的就是netty

1、TCP协议

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

 为什么要连接?

 

 

我发个请求,你回一个ack。如果收到ack证明收到了,如果没有就尝试再发一次,这样TCP在一个不可靠的信道上达到1个可靠的信号传输。

如果一个个确认,效率会低,TCP使用了流水线,批量发送,收的人可以商量1个协议,比如回ack3,代表3以前的包都收到了。批量发送有1个最大的挑战,可能会有包丢失。例如在发送时1234包,结果只收带了234包,就不能回ack,那就把收到的包缓存下来。等1过来再提交给我的上层代码。

发送方和接受方都有一个buffer,来缓存数据。发送者再收到到ack之前,先把数据缓存。buffer是可以移动的。窗口的大小就是buffer的大小,滑动窗口。

2)TCP的三次握手

 

 

客户端给发送端发送1次请求,服务端响应。客户端收到服务端的响应后,客户端发送回应。

连接,是在发送端和接收端保存一些状态,为通信准备一些 东西,准备buffer和发包的顺序。

2)Byte Stream oriented VS Message oriented

Byte Stream oriented  是没有边界的,http以这种形式发送。会出现粘包的问题

1、Socket API

     Socket() 创建1socket

     Bind() 绑定1个端口

     Listen() 监听1个端口

     Accept()  比较重要,接收1个连接(3次握手)

     Read()

   Write()

   Close()

发送窗口是和buffer有关,tcp是基于字节流的,发送窗口发送的包有多少,与网络没有关系。

浏览器输入一个域名,如何解析到IP,是通过一个DNS协议,DNS是不需要握手的。

2、BIO

1) ServerSocket  负责bind  listen   accept

2) Socket 连接

   BIO 服务器模型  thread per request/ thread per connection

Blocking io

 

 

阻塞 BIO的问题

11万个连接同时的话,就要有1万 个线程,并且阻塞等待,每个线程都占内存

21万个线程,上下文的切换

NIO

ServerSocketChannel

SocketChannel

Selector

OP_ACCEPT

OP_CONNECT

OP_READ

OP_WRITE

ServerSocketChannel 需要告诉Selector对什么感兴趣

Selector去扫描发生了哪些事件,acceptWriteread

1、BIO VS NIO

(同步/异步) * (阻塞/非阻塞)

Selector 是主动的,模型是同步的,非阻塞

Block IO也是主动的,所以它是同步、阻塞的

异步,回调函数

2、Reactor模式

反应堆

封装到handller里面。

 

  

也可以用多个Selector

 

 

 

1、手写reactor模式的挑战

1) 处理op_write事件;写忙时需要注册op_write,不忙时注销op_write

2) 处理byteBufferbyteBuffer API比较难用。

3) 处理粘包:需要记录收到的字节状态

4) 处理多个selector

5) 提供优雅的业务编程模式

6) 根据环境运行参数

一、Netty

1、 与tomcat的比较,tomcat基于http

Netty 核心概念

Channel - SocketChannel

• EventLoop - Selector

• ChannelPipeline

• ChannelHandler

• Bootstrap - Main

• ByteBuf - ByteBuffer

 

 

2ChannelHandler & Pipeline

 

 

ChannelInboundHandler 处理服务器外部发生的事件

ChannelOutboundHandler 处理服务器自己主动发的事情  bind connect read write

90%时间实现ChannelInboundHandler ChannelOutboundHandler

3、channel pipeline的关系

 

 

Handler的输入有两种类型:byteBuf message

3、粘包和拆包

 

 

Magichead 开头,第一个字节长度,在接受时还要制定规则,Magichlength要不要接收,也要制定协议。

CodecNetty实现的字节转换

ByteToMessageDecoder  

ReplayingDecoder  

MessageToMessageDecoder

理解LengthFieldBasedFrameDecoder

Length Field在帧的什么位置? length FieldOffset

Length Field自身长度是多少? LengthFieldLength

Length Field中的长度值具体指那部分? LengthAdjustment

Frame Decode后希望获得的内容(想要丢弃的帧部分) -initialBytesToStripe

 

 

 

 

用这个类,保证接收到的东西是完整的,不用自己去解决byte的边界在哪里!

NioEventloop

DefaultChannelPipeline

Netty编程要点总结

自定义handler处理事件

Handler 顺序

Context/pipleline fire 事件的不同

协议设计,解决粘包问题

 

 

 

 

 

 

 

posted @ 2021-03-24 20:25  majingyun  阅读(191)  评论(0)    收藏  举报