Linux 網路開發常見面試題回顧

shuilaner_發表於2018-11-29

一、TCP 和 UDP 有什麼不同?

      (1)在連結狀態上,TCP 是面向連結的,UDP 則是面向無連結的;

      (2)在資料傳輸的質量上,TCP 以資料流的方式傳輸,保證資料的有序性,準確性,完整性,資料傳輸質量高;UDP 則是以資料包的形式,獨立傳送資料包,不能保證資料是否到達,是否完整,是否有序,資料傳輸質量低於TCP;

      (3)在資料包的大小上,TCP 包頭 20個位元組,選項 12個位元組,但是 UDP 只有 8個位元組;

      (4)在系統資源的利用上,每個 TCP 連結,系統要維護一個 8k 的連結結構,而 UDP 則不需要;

 

二、UDP 的 connect 有什麼作用?

       UDP 的 connect  和 TCP 的 connect 不同之處在於,UDP connect 的時候只會進行對端的記錄,以及顯而易見的錯誤的檢查(比如 IP 壓根兒填錯了啊),而沒有 TCP 的三次握手操作;這時,當前的 UDP socket 也被限定於只與 connect 指定的對端通訊,當前的 socket 發生的異常也只會通知到 當前程式;同時,UDP 的 connect 是可以進行重複操作進行對端更新的,即 connect 完 A 之後,再呼叫 connect B 也是可以的,這與 TCP 不同。

      UDP 連結的兩種模式:

              (1)socket ---> sendto ---> recvfrom

              (2)socket ---> connect ---> send ---> recv 

      第二種模式也是可以使用 sendto 和 recvfrom 的,但是 引數內的 地址資訊需要置成 NULL。

 

三、TCP 連結的三次握手,四次揮手時序圖

      三次握手:

            A 發 連結包( SYN=1, SEQ=x) ,B 同意 則返回確認連結包( ACK=x+1, SYN=1, SEQ=y),A 返回確認包( ACK=y+1, SEQ=x+1)

      四次揮手:

            A 發 關閉包( FIN=1, SEQ=x), B 返回 同意包(ACK=x+1),B 傳送關閉包(FIN=1,SEQ=y), A 返回 同意包(ACK=y+1)。

 

四、TCP 和 UDP socket 伺服器端的實現流程

      TCP 伺服器端:

            socket ---> bind ---> listen ---> accept ---> close

      UDP 伺服器端:

            socket ---> bind ---> sendto ---> recvfrom ---> close

 

五、select, poll, epoll 的區別 及 選擇

      select 是採用核心輪詢方式,每次呼叫都需要輪詢 FD_SET,預設最多可以接受 1024 個fd,可更改為更大,但是隨著數量的增多,輪詢週期的變長,效能會急劇下降;

      poll 是 select 的改進版,將 FD_SET 該造成由( fd,監聽事件型別,實際事件型別 )為節點組成的鏈,解除了1024 的限制,其他並無大的區別,當 fd 多時,同樣會造成效率下降;

      epoll 將 輪詢機制 改造為 事件觸發機制,給每一個 fd 附上一個 callback,當監聽事件發生時,就將 fd 連結到 就緒連結串列,呼叫 epoll_wait 時,只用檢查就緒連結串列就可以了,而不需要像 select 和 poll 一樣進行輪詢。

      另外,select 和 poll 是將存有 fd 的結構或者陣列再每次呼叫的時候都複製到核心態,然後呼叫完再複製回使用者態,而無所謂是否有意義。epoll 使用記憶體對映,減去了這部分的data-copy操作。

      再者,從觸發方式上來看,select 和 poll 都只有 條件觸發(也可以叫水平觸發),epoll 則有條件觸發 和 事件觸發(也可以叫邊緣觸發)兩種。

      在選擇使用哪種方式的時候,需要根據 fd 的多少和活躍程度來判斷。當fd 數量較少,且都比較活躍的時候,使用 select 或者 poll 反而有可能效率更高,因為畢竟 epoll 要有多次的回撥函式。

      好東西都是要付出代價的!

 

六、epoll 有哪些事件觸發方式,各自有什麼特點和缺點,對應怎樣的程式設計解決辦法

      epoll 的事件觸發方式有兩種,Level Trigger(LT) 和 Edge Trigger(ET),按字面意思翻譯過來就是 水平觸發 和 邊緣觸發,如果按照意譯方式翻譯,可以翻譯為 條件觸發 和 事件觸發。顧名思義,條件觸發,如果滿足某個條件,則觸發,也就是說只要條件不變,每次探測都會觸發;事件觸發則是在指定事件發生時觸發,然後等待下一次事件發生再觸發。

       條件觸發(即水平觸發)會一直觸發,直到條件不滿足,也就意味著如果當前 fd 裡的任務處理不完,是可以放到下一次處理的,因為下一次探測還是會有這個fd。缺點也是這樣,如果fd 的可寫條件滿足了,寫不滿,會一直觸發可寫。

       事件觸發(即邊緣觸發)只觸發一次,如果當前來不及處理,也不會再觸發。相對來說,程式設計要複雜一些。比如當前監聽 的sockfd,如果可以accept 則 需要一直 accept 到發生 EAGAIN 錯誤,如果可以 read,則需要read 到發生 EAGAIN 錯誤,可以write 的時候也一樣,因為只有這樣才能把裡邊的資料處理完,因為下一次觸發誰知道是什麼時候,而這一次的資料沒讀完整也是不行的。

       

七、TCP 的 timewait 狀態是什麼?誰會有 timewait 狀態?timewait 狀態存在的作用是什麼?如何避免大量的 timewait 狀態佔用系統資源?

       timewait 狀態是 TCP 連結的 主動關閉方 會有的狀態,在發出最後一個 ACK 包之後,主動關閉方進入 timewait 狀態,以確保 ACK 包到達對端,以及 等待網路中之前迷路的資料包完全消失,防止在埠被複用的時候收到迷路包從而出現收包錯誤。

       timewait 狀態會持續 2MSL(max segment lifetime) 的時間,一般會有 1分鐘到4分鐘事件。這段事件內 埠不可被重分配使用。 

       timewait 並不會佔用更多系統資源,但是可以通過修改核心引數 /etc/sysctl.conf 來達到 限制timewait 數量的功能。

 

八、TCP 的頭有多少個位元組?有哪些欄位?

       TCP 頭有 20個位元組,選項12個位元組,欄位有 源埠號16位,目的埠號16位,SEQ32位,ACK32位,包頭長度4位,保留欄位6位,包型別6位,視窗大小16位,校驗和16位,緊急指標16位。之後是 可選項 8 的整數倍,資料

 

九、什麼是滑動視窗?有什麼作用?

      滑動視窗是TCP 中使用的一種提升傳輸效率和進行流量控制的方法。接收方使用滑動視窗告訴傳送方自己的緩衝區可以接收多大的資料,而傳送方則通過滑動視窗確認傳送資料的大小。滑動視窗大小位0 時,傳送方不再傳送資料。但是兩種情況除外,一種是緊急資料,一種是1位元組的資料,主要用來通知接收方確認希望接收的下一位元組和傳送方的滑動視窗大小。

 

十、connect 會阻塞,應該怎麼解決?

    (1)設定socket fd 為O_NONBLOCK 非阻塞模式

    (2)connect 會立即返回,判斷返回值,如果為0,表示建立成功,如果為 -1,則檢查 errno 是否為 EINPROGRESS,表示正在建立,否則為發生錯誤;

    (3)將 sockfd 加入 select 模型,並設定超時時間;

    (4)如果 select 返回可寫,呼叫 getsockopt 檢查 SO_ERROR,如果為 0,表示建立成功,否則失敗;

    (5)恢復 sockfd 的檔案狀態,並返回。

 

十一、如果 select 返回可讀,結果只讀到 0 位元組,這是什麼情況?

          對端關閉,可讀,read 返回 0,表示已經讀到檔案末尾。

 

十二、keepalive 是什麼?起什麼作用?起作用的過程是什麼?

         keepalive 是 TCP 協議內的心跳機制,用來維護連結的狀態,預設不開啟。伺服器端每隔一段事件會向空閒兩小時以上的連結的對端傳送一個 keepalive 包,有以下情形:

       (0)對端回覆 ACK,連結保活,再次空閒兩小時後重新探測;

       (1)對端的應用程式已經退出,TCP 回覆一個 RST包,連結關閉;

       (2)對端的應用程式卡死/無反應,TCP 回覆一個 FIN包,來終止連結;

       (3)對端機器無任何反應,伺服器端將持續傳送 keepalive 包,超時則關閉連結。時間範圍半小時到兩小時。

 

十三、列舉你知道的 TCP 選項,並說明作用

         MSS :Max Segment Size,最大分片長度,非協商值,是對資料傳送方傳送資料最大長度的限制

         SACK:Selective ACK,可選選項,即資料流傳輸過程中某一個分片丟失,可以請求只重傳這一個分片,而不用重傳丟失分片後的所有資料。

         

十四、socket 在什麼情況下可讀?

        (1) 正常有資料輸入的時候;

        (2) 有異常發生的時候,read 返回 -1,errno 置為錯誤編號;

        (3) 對端關閉的時候,read 返回 0, 表示讀檔案結束;

        (4) 當這個socket 是一個監聽 socket ,且連線數不為0,又有 SYN 進來時。

 

十五、如果連結量非常大,你會怎麼設計併發模型

          

附加:一個每秒百萬級訪問量的網際網路伺服器,每個訪問都有資料計算和 I/O 操作,如果讓你設計,你怎麼設計?

相關文章