IP、UDP初探

級別:★★☆☆☆
標籤:「IP首部」「UDP首部」「UDP」
做者: WYW
審校: QiShare團隊php


筆者最近了解了一下Python相關的內容,發現網絡編程部分很是容易可以建立一個UDP本地服務器,正好能夠用來分析一下UDP的請求和響應。在本篇文章中,筆者將給你們介紹下IP、UDP的部份內容。html

OSI、IP、UDP 簡介

聊到網絡協議,咱們經常會想到OSI(Open System Interconnection 開放式系統互聯)七層模型、TCP/IP協議簇,她位於OSI、TCP/IP協議簇哪一層等問題。python

以下圖OSI七層模型及對應的TCP/IP協議簇所示。git

  • UDP(User Datagram Protocol 用戶數據報協議)位於OSI中的第四層(傳輸層)。位於TCP/IP協議簇中的第四層(TCP or UDP)。
  • IP(Internet Protocol 網絡協議)OSI中的第三層(網絡層),位於TCP/IP協議簇中的第三層(IP)。

下圖 是OSI七層模型及對應的TCP/IP 協議簇 github

OSI TCP/IP Family

User Datagram Protocol (UDP)編程

UDP is also a transport-layer protocol and is an alternative to TCP. It provides an unreliable datagram connection between applications. Data is transmitted link by link; there is no end-to-end connection. The service provides no guarantees. Data can be lost or duplicated, and datagrams can arrive out of order.bash

UDP也是傳輸層協議,是TCP的替代方案。
它在應用程序之間提供不可靠的數據報鏈接。 數據經過連接傳輸; 沒有端到端的鏈接。
(這裏個人理解是不須要創建鏈接)該服務不保證可靠傳輸。 數據可能丟失或重複,數據報可能無序到達。服務器

Internet Protocol (IP)微信

In terms of the OSI model, IP is a network-layer protocol. It provides a datagram service between applications, supporting both TCP and UDP.網絡

在OSI模型的中,IP是網絡層協議。 它在應用程序之間提供數據報服務,支持TCP和UDP。

IP數據包首部及UDP首部

IP數據包首部格式

UDP數據包首部格式

建立本地UDP服務器、客戶端

筆者在前文提到了要用Python建立一個本地UDP服務器,而且分析UDP的請求及響應過程。這裏筆者使用的是PythonIDE、Mac自帶的終端簡單建立了一個本地UDP服務端和客戶端;

請求響應過程爲:
-> 啓動服務端
-> 啓動客戶端和服務端創建鏈接
-> 客戶端向服務端發送數據'A'
-> 服務端收到數據向客戶端發送'ABCD'。
-> 使用Wireshark對整個請求響應過程進行數據分析。

所用的Python代碼以下:

  • Python IDE做爲服務端使用以下代碼,UDP服務端代碼:
Python 3.7.1 (v3.7.1:260ec2c36a, Oct 20 2018, 03:13:28) 
[Clang 6.0 (clang-600.0.57)] on darwin
Type "help", "copyright", "credits" or "license()" for more information.
>>> from socketserver import BaseRequestHandler, UDPServer
>>> class handleRequest(BaseRequestHandler):
    def handle(self):
        print('Got connection from', self.client_address)
        msg, sock = self.request
        print('RequestMessage:',msg)
        resp = 'ABCD'
        print('Response:',resp)
        sock.sendto(resp.encode('ascii'), self.client_address)

        
>>> if __name__ == '__main__':
    serv = UDPServer(('', 20000), handleRequest)
    serv.serve_forever()

複製代碼
  • 終端做爲客戶端,使用以下代碼,UDP客戶端代碼:
from socket import socket, AF_INET, SOCK_DGRAM
s = socket(AF_INET, SOCK_DGRAM)
s.sendto('A', ('localhost', 20000))
複製代碼

示意圖以下:

UDP Server Client

抓包並進行分析

筆者結合着IP和UDP的首部示意圖,及Wireshark的請求及響應進行了以下分析:

在分析數據傳輸過程以前,筆者先對下邊會用到的名詞及工具作個簡單說明:

  • 字節byte比特bit,1個字節(byte)=8個比特(bit)。

  • ASCII碼:是基於拉丁字母的一套電腦編碼系統,主要用於顯示現代英語和其餘西歐語言。它是現今最通用的單字節編碼系統。ASCII碼對照表

  • 舉個例子'A'的ASCII碼爲0x41 基本的16進制、2進制、10進制之間的轉換: -> 16進制0x41 -> 對應2進製爲 0100 0001 -> 對應10進製爲4 * 16 + 1 = 65 在線進制轉換

  • 下圖是請求的示意圖,可見數據部分是0x41表示的是十進制的65,即'A'的ASCII碼。

    請求

  • 下圖是響應的示意圖,可見數據部分是0x41424344表示的是十進制的65 66 67 68,即'ABCD'的ASCII碼。

    響應

Snip20181218_5.png

  • 下圖標識的是IP協議所使用的版本,0100表示的是4即IPv4
    IPv4

IPv4

  • 下圖標識的是IP的首部長度,0101表示十進制5,不過這裏咱們看到Header Length 爲20字節,緣由是,Head Length的單位是4字節。(即5 * 4 字節 = 20 字節)。首部長度的最大值爲1111即15,首部長度的最大值爲15 * 4字節 = 60字節
    IP首部長度

IP首部長度

  • 服務類型部分,優先級標誌位和服務類型標誌位,被路由器用來進行流量的優先排序。筆者目前不清楚用意,暫不作解釋說明。

  • 下圖爲Total Length(總長度)顯示爲001d,16進制的d爲13,即13 + 16 = 29。指IP首部和數據報中數據以後的長度,單位爲字節。總長度爲16位,所以數據報的最大長度爲216 - 1 = 65535字節。

Total Length

Total Length

  • 下圖爲標識符,一個惟一的標識數字,用來識別一個數據報或者被分片數據包的次序。目前筆者對此並不瞭解,暫不作解釋。
    標識符

標識符

  • 下圖爲標記和分段偏移

    標記分段偏移

  • 標記:用來標識一個數據報是不是一組分片數據包的一部分。

    • Flags:0x0000
      • 其中Reserved bit 爲0 佔用1比特
      • DF(Don’t Fragment)爲0,佔用1比特;表明不分片;
      • MF(More Fragemnt)爲0,佔用1比特,MF爲0,若是在分片的狀況下,表明這是若干分片中的最後一個;
      • 分片偏移爲0,佔用 13比特;0 0000 0000 0000
  • 分段偏移:一個數據包是一個分片,這個域中的值就會被用來將數據報以正確順序從新組裝。目前筆者對此並不瞭解,暫不作解釋。

  • 下圖爲Time to live (存活時間),用來定義數據報的生存週期,以通過路由器的條數/秒數 進行秒數。目前筆者對此並不瞭解,暫不作解釋。佔用8個比特,16進制0x40即十進制64。

Time to live

Time to live

  • 下圖爲協議,用來識別在數據包序列中上層協議數據類型。佔用8個比特,16進制0x11即十進制17。表明UDP。
    協議

協議

  • 下圖爲首部校驗和,一個錯誤檢測機制,用來肯定IP首部的內容有沒有被損壞或者篡改。佔用16個比特
    首部校驗和

首部校驗和

  • 下圖爲源IP地址,即發出數據報的主機的IP地址。佔用32個比特。16進制的0x7f表明的127,0x7f00 0001 表示127.0.0.1

源IP地址

源IP地址

  • 下圖爲目的IP地址,數據報目的地的IP地址。佔用32個比特。16進制的0x7f表明的127,0x7f00 0001 表示127.0.0.1。

目的IP地址

目的IP地址

上述內容就是IP的數據報首部的相關分析,下邊筆者將給你們介紹下UDP的首部的相關內容:

  • 以下圖UDP的首部所示,UDP的首部佔用 64比特,即8個字節

UDP的首部

UDP的首部

  • 下圖表示UDP的源端口,佔用16比特。16進製爲0x f432即爲十進制的62514

UDP的源端口

UDP的源端口

  • 下圖表示UDP的目標端口,佔用16比特。16進製爲0x 4e20即爲十進制的20000
    UDP的目標端口

UDP的目標端口

  • 下圖表示UDP數據報的字節長度,表示數據報的字節長度。長度佔用UDP首部16比特。16進製爲0x 0009即爲十進制的9(由於UDP首部長度佔8個字節,加上傳輸了一個數據'A'佔用1個字節,共9字節)。

UDP數據報的字節長度

UDP數據報的字節長度

  • 下圖表示UDP數據報的校驗和,用來確保UDP首部和數據到達時的完整性。校驗和佔用UDP首部16比特,16進製爲0x fe1c。目前筆者對這個值並不瞭解,暫不作解釋。

UDP數據報的校驗和

UDP數據報的校驗和

  • 最後,傳輸的數據,包含被UDP封裝進去的數據,包含應用層協議頭部和用戶發出的數據,咱們傳輸的'A',以下圖,顯示爲16進制的0x41即十進制的65。
    傳輸的數據

參考內容:


小編微信:可加並拉入《QiShare技術交流羣》。

關注咱們的途徑有:
QiShare(簡書)
QiShare(掘金)
QiShare(知乎)
QiShare(GitHub)
QiShare(CocoaChina)
QiShare(StackOverflow)
QiShare(微信公衆號)

推薦文章:
iOS 多線程之GCD
iOS 多線程之NSOperation
iOS 多線程之NSThread
iOS Winding Rules 纏繞規則
iOS 簽名機制
iOS 掃描二維碼/條形碼
奇舞週刊

相關文章
相關標籤/搜索