什麼程度才算精通TCP/IP?

shiyichuan2005


由於我們大部分時間都工作在應用層,下層的事情不用我們操心;其次網絡協議體系本身就很複雜龐大,入門門檻高,因此很多人都不清楚TCP/IP的工作原理。要想精通TCP/IP的工作原理,就是需要明白。

一個主機的數據要經過哪些過程才能發送到對方的主機上


TCP/IP的結構組成

TCP/IP 協議採用4層結構,分別是應用層、傳輸層、網絡層和鏈路層,每一層都呼叫它的下一層所提供的協議來完成自己的需求。還有一種說法TCP/IP是5層結構。就是在4層基礎上加入了物理層。而4層是把物理層層歸到了鏈路層當中。

<strong>

結構功能組成

  • 鏈路層:把數據通過物理介質傳送給對方。對0和1進行分組,定義數據幀,確認主機的物理地址,傳輸數據;

  • 網絡層:定義IP地址,確認主機所在的網絡位置,並通過IP進行MAC尋址,對外網數據包進行路由轉發;

  • 傳輸層:定義端口,確認主機上應用程序的身份,並將數據包交給對應的應用程序;

  • 應用層:定義數據格式,並按照對應的格式解讀數據。

綜上所述
當你輸入一個網址並按下回車鍵發送的時候,首先,應用層協議對該請求包做了格式定義;緊接著傳輸層協議加上了雙方的端口號,確認了雙方通信的應用程序;然後網絡協議加上了雙方的IP地址,確認了雙方的網絡位置;最後鏈路層協議加上了雙方的MAC地址,確認了雙方的物理位置,同時將數據進行分組,形成數據幀,採用廣播方式,通過傳輸介質發送給對方主機。而對於不同網段,該數據包首先會轉發給網關路由器,經過多次轉發後,最終被髮送到目標主機。目標機接收到數據包後,採用對應的協議,對幀數據進行組裝,然後再通過一層一層的協議進行解析,最終被應用層的協議解析並交給服務器處理。


PHP智慧與能力




從使用套接字編程的角度,我認為要掌握以下知識點:

  1. 瞭解OSI七層模型和TCP/IP五層模型,明白當應用層調用send函數將純數據寫入緩存後,數據經過每一層會加上什麼頭數據;以及網卡收到數據後,數據經過每一層會去掉什麼頭數據。
  2. 熟悉以太網幀格式,能夠輕鬆使用wireshark、tcpdump等抓包工具或指令,分析幀內容;
  3. 熟悉套接字編程方法,熟練掌握bind,connect,listen,accept,send/sendto,recv/recvfrom,setsockopt等函數。明白TCP與UDP協議下的編程方法;
  4. 理解TCP協議的三次握手和四次揮手過程,知道TCP和UDP通信協議的特點和差異,在不同的應用中能夠分析出使用哪種協議最合適;
  5. 明白交換機、路由器的區別,知道路由表的作用,理解ARP、ICMP協議通信過程,當網絡不通時,能夠使用arp -a,ping等指令進行問題定位;

基本就是以上幾點,當然這只是從編程的角度來講的,如果你是一名網絡管理員或網絡工程師,那要學習的東西就更多了!


Gfilsxin


去下載一份Linux內核源碼,找到TCP/IP協議棧的源碼,能看懂了,就成了。


碼師傅


1、A進程通過TCP向另一臺機器上的B進程發送了一個字符串“hello”,TCP返回對方成功接收的確認信息,請問,現在進程A是否可以肯定地說進程B收到了它發送的字符串?

答案:不能!舉反例,進程B所在機器的TCP收到進程A發送的“hello”信息後,告訴進程A發送成功,但有可能沒有立即將數據交給進程B,而是放在自己的緩衝區中,等待進程B讀取,如果機器此時突然掉電,緩衝區中的信息將丟失,進程B將不可能收到“hello”字符串。

2、有什麼辦法來儘量避免上述情況的發生呢?

答案:將TCP報文段首部中的PSH標誌置1,這樣會讓B端的TCP協議收到數據後儘快交給進程B,能不緩存儘量不要緩存。

3、我們知道通常TCP連接的建立需要3次握手,關閉需要4次握手,為什麼關閉會多一次呢?

答案:簡單說,就是TCP允許半關閉狀態的存在。當進程A向進程B發送FIN,B也向A發送確認後。此時此刻的狀態就是半關閉狀態,A發送的FIN就是告訴B:“我要發送的數據都發送完了”但B沒有發送FIN給A,有可能代表B還有沒發送完的數據,如果B也發送完數據了,B就發送FIN給進程A,進程A確認B發送的FIN,這時,雙方都已經發送完了數據,連接就斷開了,TCP回收相關資源。

4、假如服務器突然掉電重啟,但客戶端並不知情,請問此時二者之間的TCP連接處於什麼狀態?

答案:處於半打開狀態。就是客戶端還覺得連接是正常的,服務器這邊已經沒有連接的任何信息了。

5、那麼,假如此時客戶端通過這個連接向服務器請求數據,服務器會怎麼應對呢?

答案:服務器收到客戶端的請求會進行一次ARP查詢,獲得客戶端MAC地址,然而由於已經丟失了所有連接信息,此時的服務器是一臉懵逼(就像喝了孟婆湯!),於是乎,它會發一個RST給客戶端,表示:“哥們,我不認識你,想跟我說話請先發送SYN!”

6、假如客戶端按照服務器的要求重新建立連接,卻搞錯了服務器的端口號,會發生什麼情況呢?

答案:有兩種可能,一種是服務器端的TCP收到客戶端請求,查看本機上是否有進程在監聽相應的端口,如果有,就把請求交給這個進程,一般而言,這個進程不會接受這個連接的,於是它會發一個RST給客戶端。還有一種可能是TCP沒有找到哪個進程在監聽相應的端口,於是TCP就會直接發一個RST給客戶端,一般而言都會是這種情況。

7、假如現在有一個多進程服務器,服務器進程為A,接受一個連接後新建一個進程B來處理連接,再接受一個連接後又建一個進程C來處理這個連接,請問,進程ABC是否監聽同樣的端口?

答案:是!

8、那TCP接收到發送給這個端口的報文段,怎麼決定發給哪個進程呢?

答案:首先,所有的SYN報文段都會發送給服務器進程A,其他的報文段依據<port>這個四元組來決定發送給進程B還是進程C。/<port>

9、假如上面的服務器進程A收到一個連接請求,正在為這個請求創建處理進程的時候,又有新的連接請求進來了,TCP會怎麼處理呢?

答案:一般情況下,服務器進程A會給TCP一個指示,讓TCP維護一個適當長度的連接隊列,TCP與新連接請求完成三次握手後,就會把這個連接放入連接隊列中,服務器進程A會在合適的時候來從這個隊列中取連接。

10、這個連接對列是否會對服務器的併發處理能力產生影響呢?如果會,會有什麼影響?

答案:不會!二者沒有必然關係。

11、MSS和MTU各是什麼,二者是什麼關係?

答案:MSS是TCP最大報文段長度,就是TCP發送數據需要對數據分段時,最大的段的字節數。MTU是最大傳輸單元,通常由網卡的硬件特性規定,表示通過該網卡傳輸的數據單元最大的字節數。MSS要受同一臺機器上的MTU限制。比如MTU為1500字節,那麼MSS就只能是1460字節,這是因為1460字節的數據在通過網卡向外傳輸時,會加上20字節的ip頭和20字節的tcp頭。

12、假設機器A和B的MSS分別是1400和1600,請問,A通過TCP向B發送數據時,是否可以發送長度為1600字節的數據段?

答案:不可以,雖然發送1600字節的數據段沒有突破B的MSS,但是突破了A自己的MSS。這樣一來,當這1600字節的數據段通過A的網卡向B發送時,會被切分為2個IP片,每個為840字節,以保證不突破A的MTU,這顯然降低了傳輸的效率,因為兩個840字節中有著相同的IP頭和TCP頭。

13、機器A和B有一條TCP連接,假如A想盡快斷開連接,應當怎麼辦?

答案:A可以直接給B發送一個RST,就可以了,相當於告訴B,我關閉連接了,你看著辦吧。這叫做異常關閉。

14、B的TCP收到A發來的RST,會怎麼辦?

答案:B的TCP會告訴上層的進程,連接已經斷開了,然後就會回收這條連接的資源,並不會發送任何確認信息給A。所謂你無情休怪我不義。

15、假設A正常斷開與B的TCP連接,當收到B的FIN時,A發送ACK給B,是否就算完成了4次握手,連接已經成功斷開?

答案:不是,A的TCP會啟動一個定時器,等待2MSL的時間,這主要是為了防止A的ACK沒有成功傳到B,讓B以為自己的FIN沒有送到A處,反覆重傳FIN的問題。2MSL的時間到時,如果A沒有再次收到B的FIN,說明B成功收到A的ACK,A就可以安全地斷開這個連接,若期間再次收到B的FIN,則A會重傳ACK。


分享到:


相關文章: