! https://zhuanlan.zhihu.com/p/145958515
(这个系列暂停一段时间,接下来看数据库
握手内核实现
其实我觉得网络编程很straight forward,比内存要straight forward多了。
怎么写listen, accept最简单的TCP读写功能不说了。说一个内核里的实现。

内核里面有2个队列:SYN队列和ACCEPT队列,accept()是从ACCEPT队列里取一个分组返回一个socket,三次握手是在这之前就由内核全部做完了,连接已经处于established状态。另外,backlog参数,规定的是SYN队列(内核2.2后改了,图错了:https://www.cnblogs.com/orgliny/p/5780796.html)的大小,也就是还未建立连接的socket数量(也不太准确,有可能建立了连接,但是ACCEPT队列满了,移动不过去)。这2个队列大小都可以调。
这张图也讲的可以:

讲的比我详细多了:[译] TCP的SYN队列和Accept队列 - 就想叫yoko的文章 - 知乎 https://zhuanlan.zhihu.com/p/87437843
网络编程模型
总之就是 单进程 -> 多进程 -> 多线程 -> I/O 复用 + 多线程 -> 异步I/O + 协程 + epoll(应该是未来)
epoll select poll 怎么用的例子,网上都有。
讲讲不同:
select最受鄙视,因为受文件描述符1024大小限制。
poll中庸。
epoll提升了2个点:
- 内核监听I/O事件的时候,采取的是有人按铃,空姐直接问按铃人需要什么服务。没有多路复用的时候,是空姐不断问每一位乘客需不需要帮助,循环往复。 Select,poll的时候,是有人按铃,空姐才把所有乘客问一遍需要什么服务。 显而易见的性能提升。这里乘客代指监听的socket或者I/O事件,内核是空姐。
- 返回的事件集合是经过挑选的,只有发生了变化的事件才返回,也就是说,返回的事件都是需要处理的。这点,很多人写过select,poll程序就知道,你每次都需要遍历所有事件集合中的事件来查找你想找的事件。epoll直接帮你filter掉。
