netty权威指南 180
bio、nio、aio的区别?
bio -- 伪异步io -- nio -- aio
bio同步阻塞,nio同步非阻塞,aio异步非阻塞。
epoll
nio是基于多路复用器来实现同步非阻塞的,多路复用器又是基于epoll函数实现的。
- 文件列表fd:代表linux文件系统,用来存储所有涉及的数据
- socket队列:数据结构为红黑树,用来存储socket,每个socket代表一个客户端连接,每个socket都持有eventPoll的引用
- 工作队列-进程A、B:可以理解成当前运行的进程(线程),CPU挨个执行他们
- rdlist:链表结构,用来存储就绪状态的socket(有真正数据过来的socket)
- eventPoll:工作进程和socket的中间层,rdlist是它的一个成员,还有一个队列用来存储进程(进程A)
int s = socket(AF_INET, SOCK_STREAM, 0);
bind(s, ...)
listen(s, ...)
int epfd = epoll_create(...);
epoll_ctl(epfd, ...); //将所有需要监听的socket添加到epfd中
while(1){
int n = epoll_wait(...)
for(接收到数据的socket){
//处理
}
}
- 执行epoll_create函数:cpu创建eventpoll对象
- 调用epoll_ctl函数:cpu添加socket到文件系统,同时将eventpoll设置到socket中
- 执行epoll_wait:将进程A添加到eventpoll的队列并且阻塞。
- 当socket有真正数据过来的时候,cpu通过该socket的eventpoll引用,将socket添加到eventpoll的rdlist中。同时cpu会唤醒进程A,进程A就会查询rdlist,在rdlist中发现有就绪的socket,直接带着socket进入工作队列等待cpu调用执行
缓冲区、管道、流
tcp粘包、拆包
- 什么是tcp粘包、拆包?
- 解决粘包:LineBasedFreameDecoder和StringDecoder。按照分割符【
】【
】划分消息
案例:client循环向server发送100条消息,服务端可能按照两条消息接受。
3.delimiterBaseFrameDecoder:按照分割符划分消息,可以自己指定分割符
4.fixedLengthFrameDecoder:按照固定长度划分消息
编解码
- java序列化:最大的缺点无法跨语言。基本不会被框架使用。 其他缺点:序列化后占用空间大、性能低
- protobuf:google的序列化框架,序列化框架很多,protobuf是比较主流的一个
3.thrift:序列化框架,适合大型数据传输,静态文件
4.JSON
5.messagePack: