tcp链接以及网络I/O的几个问题

    这段时间在作一些web方面开发的事情,用的Nginx+fast-cgi,计划深刻看一下Nginx的内部实现和架构,以方便理解和调优。后面准备写一篇有关Nginx介绍和深度解析的文章,要深刻理解web服务器的工做原理,网络编程的基本概念和知识不可或缺。这篇文章先对于网络编程中比较容易混淆的几个问题作一个复习和总结,主要参考自《unix网络编程》这本书。web

    首先,简单总结一下传输层tcp协议的两个琐碎的点。编程

    一、TIME_WAIT状态问题:tcp三次握手创建链接,四次挥手来释放链接,这个你们都熟悉。在释放链接时,主动发起关闭链接的一方的一方会在发送最终确认ack后会有一个TIME_WAIT的状态,以下图所示:服务器

    这个状态的持续时间通常是2MSL(maximum segment lifetime),也就是2倍的最长分节生命周期,对于MSL,比较老的数据是30s到2min之间。这个状态存在的理由,有两点:a)、实现终止TCP全双工链接的可靠性(由于客户端的最终ACK可能丢失,从而服务器端会再次发送FIN请求,客户端须要可以应对这种状况的发生,等待新的FIN请求到达后,能够再发送一次最终ACK。旧的ACK丢失到新的FIN到达的时间间隔,最大就是2MSL);b)、容许老的重复分节在网络中消逝(也即,一样的ip、端口创建新的链接时,新的tcp链接和旧的tcp链接的四元组相同,TIME_WAIT状态的引入能够避免将旧的tcp链接网络延迟的数据当作新的tcp链接的数据)网络

    二、四元组,socket套接口用来识别不一样tcp链接的一个数据结构,(本地IP地址,本地tcp端口号,远程IP地址,远程tcp端口号),四元组只要有一项不一样,就能够认为是不一样的链接。其中端口号是一个16bit的数,单机端口数目的最大值是65535。前两天水木上有一个问题,关于多机Nginx作服务器时,最大链接数什么的,具体问题可能要更复杂一些,记不清楚了,但如何判断什么的仍是离不开这些基础知识,那个当时我存了合集,有空再去研究一下那个问题。数据结构

    下面,总结澄清一下阻塞、非阻塞、IO复用、异步、同步、信号驱动的区别和联系,这些是网络编程中比较容易混淆的概念。架构

    整体上讲,应用程序从网络中拿数据,要经历两个阶段:一、数据分组到达网络,并被拷贝到内核的某个缓冲区中,数据报准备好;二、数据从内核缓冲区拷贝至用户态应用程序的缓冲区。基于这两个过程,下面先给出各类IO模式的调用图,最后给出异步、同步IO等区分等。异步

    阻塞I/O:socket

 

    非阻塞I/O:tcp

    I/O复用模型(select、poll等):spa

 

    信号驱动IO模型:

    异步I/O模型:

 

    各类I/O模型的对比,除了异步I/O,其余几种I/O模型等的主要区别在第一阶段也即得知数据报准备好这一过程,第二个阶段(从内核向应用程序缓冲区拷贝)都同样,而异步I/O的两个阶段都与其余模型不同:

    阻塞什么的理解了,那么到底什么是同步I/O、什么是异步I/O呢,Posix.1的响应术语定义以下:

    同步I/O:操做引发请求进程阻塞,直到I/O操做完成,所以阻塞I/O、非阻塞I/O(注意,非阻塞只是接受数据的第一阶段,第二阶段仍是阻塞的)、I/O复用模型和信号驱动型I/O模型都是同步I/O模型;

    异步I/O:不引发请求进程阻塞,所以只有上面两个阶段都不阻塞的异步模型才是符合定义的异步I/O。

相关文章
相关标签/搜索