前几天忙了下科研的事情,抽出空来继续学习一下muduo,本章开始正式学习muduo网络库,一点点深入linux多线程服务器的内部。好了,加油,开始了。
TCP编程本质
基于事件的非阻塞网络编程是高性能并发网络服务器的主流模式。其实之前的博文已经提到过reactor模型。简单来讲就是:注册某个事件的回调,当这个事件发生时,网络库会调用此函数,直接将事情为自己所用,进行内部处理。
作者认为,TCP做了三件半的事情:
- 连接的建立,服务端接受和客户端发起,连接后两者即对等,可以互收发数据。
- 连接的断开,消息传递完毕的主动断开和被动断开。
- 消息到达,文件描述符可读。对此事的处理就是网络编程性能的区别所在。
- 也许应该是3.5,消息发送完毕。数据写入操作系统缓存区,由TCP协议栈负责区别发送,不是说对方收到了数据。(之前我们说过,TCP不会说一个字符一个字符来了就发,分包之类的都是根据实际情况来发送的。)
之后,作者提到了很多TCP的小细节,这个多少我们都在TCP的那篇里提到过。这里择出一个需要好好考虑的细节。
非阻塞网络编程中,为什么要使用应用层发送缓存区?
假设要发送40k,而TCP缓存区只有25k时,应该怎么处理?显然不能阻塞等待此缓存区可用,阻塞势必会造成线程的收发问题。所以网络库需要有应用层缓存区来存储多出的数据,让此缓存区来等待socket可用,这样发送程序便不会阻塞。当新的数据来临时,如果此时socket可用,也不能直接进入socket缓存区发送,因为如果此时应用层缓存区有上次剩下的数据的时候,就会出现顺序的混乱,所以我们要将所有的发送数据追加到应用层缓冲区的末尾。
剩下的有兴趣可以自己去看。
echo——muduo示例
以一个经典的echo回显为例,讲述三个半事件。
首先定义一个echo基类,观察里面的成员。构造函数,回调函数,循环体和server。
构造函数里就直接定义回调函数,连接回调和发送回调。
定义回调函数。
可以看到,这就是事件驱动,程序被动等待事件发生,然后通过回调调用事件注册的处理函数。
需要注意的是,connection参数是我们之前说过的shred_ptr。onmessage函数参数是收到的tcp连接。
进入loop循环。
性能评测
这一部分作者对muduo库进行了对比,由于我对这方面不太了解,所以只是阅读的方式进行全文通读,暂时不知道怎么总结。
性能测试的原则:采用对方的性能测试方案,用muduo实现相同的测试,然后在软硬件中对比。
正式开始网络库后,知识点就多了起来,此文章只做本人笔记之用,想完整了解muduo,光看博客是不够的。结合书和源码,然后参考博客,才是正确的学习之道。