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() 创建1个socket
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的问题
1)1万个连接同时的话,就要有1万 个线程,并且阻塞等待,每个线程都占内存
2)1万个线程,上下文的切换
NIO
ServerSocketChannel
SocketChannel
Selector
OP_ACCEPT
OP_CONNECT
OP_READ
OP_WRITE
ServerSocketChannel 需要告诉Selector对什么感兴趣
Selector去扫描发生了哪些事件,accept、Write、read
1、BIO VS NIO
(同步/异步) * (阻塞/非阻塞)
Selector 是主动的,模型是同步的,非阻塞
Block IO也是主动的,所以它是同步、阻塞的
异步,回调函数
2、Reactor模式
反应堆
封装到handller里面。

也可以用多个Selector

1、手写reactor模式的挑战
1) 处理op_write事件;写忙时需要注册op_write,不忙时注销op_write
2) 处理byteBuffer:byteBuffer API比较难用。
3) 处理粘包:需要记录收到的字节状态
4) 处理多个selector
5) 提供优雅的业务编程模式
6) 根据环境运行参数
一、Netty
1、 与tomcat的比较,tomcat基于http。
Netty 核心概念
Channel - SocketChannel
• EventLoop - Selector
• ChannelPipeline
• ChannelHandler
• Bootstrap - Main
• ByteBuf - ByteBuffer

2、ChannelHandler & Pipeline

ChannelInboundHandler 处理服务器外部发生的事件
ChannelOutboundHandler 处理服务器自己主动发的事情 bind connect read write
90%时间实现ChannelInboundHandler 和 ChannelOutboundHandler
3、channel 和pipeline的关系

Handler的输入有两种类型:byteBuf 和message
3、粘包和拆包

Magichead 开头,第一个字节长度,在接受时还要制定规则,Magich和length要不要接收,也要制定协议。
Codec。Netty实现的字节转换
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 事件的不同
协议设计,解决粘包问题
浙公网安备 33010602011771号