1.应用层缓冲区Buffer设计
-
muduo的IO模型是IO复用,且fd是非阻塞模式,若使用阻塞模式,IO线程可能阻塞在read,write等系统调用,这样的话,其他fd的IO事件到来,IO线程也不能够及时处理,也就不能最大限度的使用IO线程
-
为什么需要有应用层缓冲区(详见MuduoManual.pdf P76)
(1)2.4.2 为什么 non-blocking 网络编程中应用层 buffer 是必须的?
(2)2.4.3 Buffer 的要求
(3)2.4.4 Muduo Buffer 的数据结构)
(4)2.4.5 Muduo Buffer 的操作
应用层的发送缓冲区output buffer,应用层的接收缓冲区input buffer -
eg:36\jmuduo\muduo\net\Buffer.h
36\jmuduo\muduo\net\Buffer.cc
36\jmuduo\muduo\net\CMakeLists.txt
2.epoll使用LT模式的原因
- 与poll兼容
- LT模式不会发生漏掉事件的BUG,但POLLOUT事件不能一开始就关注,否则会出现busy loop,而应该在write无法完全写入内核缓冲区的时候才关注,将未写入内核缓冲区的数据添加到应用层output buffer,直到应用层output buffer写完,停止关注POLLOUT事件。
- **读写的时候不必等候EAGAIN,可以节省系统调用次数,降低延迟。(**注:如果用ET模式,读的时候读到EAGAIN(要把内核缓冲区读完才行,若只读一部分,即使今后数据再到来也不会给通知了,一直都处于高电平的状态,不会再触发了),写的时候直到output buffer写完或者EAGAIN(要把内核缓冲区写满才行,若没有写满,下次再写入就不会再通知是否可写入了,ET模式只通知一次))
- libevent,boost::asio都是用的是LT模式。都说ET模式效率高,但不见得。
3.其他缓冲区设计方案
- 详见MuduoManual.pdf 2.4.6 其他设计方案
4.TcpConnection中增加send
-
eg:37\jmuduo\muduo\net\TcpConnection.h
37\jmuduo\muduo\net\TcpConnection.cc
37\jmuduo\muduo\net\TcpServer.cc
37\jmuduo\muduo\net\Callbacks.h -
eg测试:37\jmuduo\tests\Reactor_test11.cc
jmuduo\tests\CMakeLists.txt -
测试:
telnet作为客户端客户端能发送数据,服务端还能回射回来
nc作为客户端
5.TcpConnection中shutdown的处理方法
-
应用程序想关闭连接,但是有可能正处于发送数据的过程中,oupt Buffer中有数据还没有发完,是不能直接调用close()的。
conn->send(buff);
conn->shutdown();判断一下是否还有正在发送的数据,若还有正在发送的数据,则不应该关闭。 -
eg:37\jmuduo\muduo\net\TcpConnection.cc
37\jmuduo\muduo\net\Channel.cc -
eg测试:37\jmuduo\tests\Reactor_test12.cc
37\jmuduo\tests\CMakeLists.txt -
测试:服务端主动关闭连接
客户端使用nc测试
服务端主动关闭连接,服务端不会进入到37\jmuduo\muduo\net\Channel.cc的if ((revents_ & POLLHUP) && !(revents_ & POLLIN))
-
eg测试:37\testcli.c
服务端:37\jmuduo\tests\Reactor_test11.cc -
测试:客户端故意等待10s再调用close()
服务端过了10s后,HUP和IN事件才到来