TCP:三個角度看TCP連接建立與結束

前言

本文的核心在於 看問題的角度和圖例 ;閱讀前提是瞭解TCP連接的大致過程,通過本文可以更加深入的瞭解連接建立的細節;本文同時是兩個TCP常見面試題的答案: (1) 描述TCP連接建立和斷開的過程; (2) TCP連接中accept系統調用發生在哪一步;

信息傳遞角度

從信息傳遞角度看,信息傳遞的標識是SYN,標識了開始建立連接並互換信息,交換的信息有:

  1. client的ip和port,也就是通知服務端鏈接人的地址;
  2. 雙方互換了開始計數的sequence number,也就是ISN;
  3. 雙方協商了MSS;
  4. 雙方溝通了window size;


TCP:三個角度看TCP連接建立與結束


狀態流轉角度

從連接的建立和結束過程的狀態流轉來看,連接的正常狀態如下圖;信息交換之後,兩端的聯繫狀態會發生變化;打個比方,人和人之間瞭解了彼此的情況溝通交流之後,關係的狀態也會發生變化。


TCP:三個角度看TCP連接建立與結束


系統調用角度

最後看一下什麼操作導致了信息的傳遞和狀態的變化,有些是用戶進程通過system call觸發的(綠色表示),有些是kernel按rfc對於tcp的規定實現的。


TCP:三個角度看TCP連接建立與結束


這裡涉及的系統調用包括:socket,listen,bind,accept,connect,close;

accept拓展詳解

這張圖中accept畫在了server establish的後面,這裡具體展開解釋一下accept方法。給accept過多關注有兩個原因:這個操作容易產生誤解,筆者第一次看tcp server的過程中以為accept是連接建立的一部分,畢竟大部分講tcp server的例子裡accept會block住直到返回一個已經建好的連接;第二個原因是accept在面試中常常被問到。

這裡先看一下linux manual裡accept的api定義:

   #include              #include    int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
  1. accpet用於需要建立連接的socket。 也就是UDP這種server並不需要accept,TCP這種需要連接的傳輸協議才需要調用accept函數。
  2. accept的作用是1-從監聽socket的隊列中取得第一個2-等待處理的連接pending connection,並3-創建一個新的已經處於連接狀態的socket 並返回這個socket的fd。這句話中包含了3個關鍵信息,其中3信息中有2個socket和一個連接:第一個socket是accept需要知道listening socket是哪個,要從這個監聽socket的連接隊列中拿到這個等待處理的連接;第二個是拿到連接之後,accept直接創建一個connected socket與之對應;從這裡可以看到connection本身已經存在於queue中,
    accept的作用實際是從queue中拿出一個連接而已,這個就解釋了accept實際是發生在三次握手之後。實際一個listening socket有兩個隊列,一個隊列處理正在握手過程中的connection,另一個隊列處連接建立完成的connection,accept取得的是握手已經完成並等待用戶進程處理的連接;
  3. accept是否阻塞可以通過listening socket的選項控制:大部分例子裡accept會阻塞caller進程直至返回一個connected socket,但是這個是可以控制的,這裡就涉及“socket options”,當socket被設置為nonblocking時如果沒有連接可以拿accept不會一直blocking,會直接返回error;

昇華一下

連接的建立有(1)動作,動作使得(2)信息的交換,信息的交換使得(3)狀態發生改變。這裡”動作-信息-狀態“也可以看作一種結構性分析的方法,這個方法可以來幫忙設計各種場景下的狀態機:什麼核心操作,核心信息變化,應該是一種狀態。

希望這三個角度能加深您對TCP的認識哦:)

作者:二喵鏈接:https://juejin.im/post/5e313ac951882536a628017b來源:掘金著作權歸作者所有。商業轉載請聯繫作者獲得授權,非商業轉載請註明出處。


分享到:


相關文章: