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。

相關文章
相關標籤/搜索