級(jí)別:★★☆☆☆
標(biāo)簽:「IP首部」「UDP首部」「UDP」
作者: WYW
審校: QiShare團(tuán)隊(duì)
筆者最近了解了一下Python相關(guān)的內(nèi)容幌墓,發(fā)現(xiàn)網(wǎng)絡(luò)編程部分非常容易能夠創(chuàng)建一個(gè)UDP本地服務(wù)器囱稽,正好可以用來分析一下UDP的請(qǐng)求和響應(yīng)。在本篇文章中翰意,筆者將給大家介紹下IP、UDP的部分內(nèi)容巾兆。
OSI猎物、IP、UDP 簡(jiǎn)介
聊到網(wǎng)絡(luò)協(xié)議角塑,我們常常會(huì)想到OSI(Open System Interconnection 開放式系統(tǒng)互聯(lián))七層模型蔫磨、TCP/IP協(xié)議簇,她位于OSI圃伶、TCP/IP協(xié)議簇哪一層等問題堤如。
如下圖OSI七層模型及對(duì)應(yīng)的TCP/IP協(xié)議簇所示。
- UDP(User Datagram Protocol 用戶數(shù)據(jù)報(bào)協(xié)議)位于OSI中的第四層(傳輸層)窒朋。位于TCP/IP協(xié)議簇中的第四層(TCP or UDP)搀罢。
- IP(Internet Protocol 網(wǎng)絡(luò)協(xié)議)OSI中的第三層(網(wǎng)絡(luò)層),位于TCP/IP協(xié)議簇中的第三層(IP)侥猩。
下圖 是OSI七層模型及對(duì)應(yīng)的TCP/IP 協(xié)議簇
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.
UDP也是傳輸層協(xié)議榔至,是TCP的替代方案。 它在應(yīng)用程序之間提供不可靠的數(shù)據(jù)報(bào)連接欺劳。 數(shù)據(jù)通過鏈接傳輸; 沒有端到端的連接唧取。 (這里我的理解是不需要建立連接)該服務(wù)不保證可靠傳輸铅鲤。 數(shù)據(jù)可能丟失或重復(fù),數(shù)據(jù)報(bào)可能無序到達(dá)枫弟。
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是網(wǎng)絡(luò)層協(xié)議。 它在應(yīng)用程序之間提供數(shù)據(jù)報(bào)服務(wù)淡诗,支持TCP和UDP骇塘。
IP數(shù)據(jù)包首部及UDP首部
創(chuàng)建本地UDP服務(wù)器、客戶端
筆者在前文提到了要用Python創(chuàng)建一個(gè)本地UDP服務(wù)器韩容,并且分析UDP的請(qǐng)求及響應(yīng)過程款违。這里筆者使用的是PythonIDE、Mac自帶的終端簡(jiǎn)單創(chuàng)建了一個(gè)本地UDP服務(wù)端和客戶端宙攻;
請(qǐng)求響應(yīng)過程為:
-> 啟動(dòng)服務(wù)端
-> 啟動(dòng)客戶端和服務(wù)端建立連接
-> 客戶端向服務(wù)端發(fā)送數(shù)據(jù)'A'
-> 服務(wù)端收到數(shù)據(jù)向客戶端發(fā)送'ABCD'奠货。
-> 使用Wireshark對(duì)整個(gè)請(qǐng)求響應(yīng)過程進(jìn)行數(shù)據(jù)分析。
所用的Python代碼如下:
- Python IDE作為服務(wù)端使用如下代碼座掘,UDP服務(wù)端代碼:
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))
示意圖如下:
抓包并進(jìn)行分析
筆者結(jié)合著IP和UDP的首部示意圖溢陪,及Wireshark的請(qǐng)求及響應(yīng)進(jìn)行了如下分析:
在分析數(shù)據(jù)傳輸過程之前萍虽,筆者先對(duì)下邊會(huì)用到的名詞及工具做個(gè)簡(jiǎn)單說明:
字節(jié)
即byte
,比特
即bit
形真,1個(gè)字節(jié)(byte)=8個(gè)比特(bit)杉编。ASCII碼:是基于拉丁字母的一套電腦編碼系統(tǒng),主要用于顯示現(xiàn)代英語(yǔ)和其他西歐語(yǔ)言咆霜。它是現(xiàn)今最通用的單字節(jié)編碼系統(tǒng)邓馒。ASCII碼對(duì)照表
舉個(gè)例子'A'的ASCII碼為0x41
基本的16進(jìn)制、2進(jìn)制蛾坯、10進(jìn)制之間的轉(zhuǎn)換:
-> 16進(jìn)制0x41
-> 對(duì)應(yīng)2進(jìn)制為 0100 0001
-> 對(duì)應(yīng)10進(jìn)制為4 * 16 + 1 = 65 在線進(jìn)制轉(zhuǎn)換-
下圖是
請(qǐng)求
的示意圖光酣,可見數(shù)據(jù)部分是0x41
表示的是十進(jìn)制的65,即'A'的ASCII碼脉课。
請(qǐng)求 -
下圖是
響應(yīng)
的示意圖救军,可見數(shù)據(jù)部分是0x41424344
表示的是十進(jìn)制的65 66 67 68,即'ABCD'的ASCII碼倘零。
響應(yīng)
- 下圖標(biāo)識(shí)的是
IP協(xié)議所使用的版本
唱遭,0100表示的是4即IPv4
IPv4
- 下圖標(biāo)識(shí)的是
IP的首部長(zhǎng)度
,0101表示十進(jìn)制5呈驶,不過這里我們看到Header Length 為20字節(jié)拷泽,原因是,Head Length的單位是4字節(jié)。(即5 * 4 字節(jié) = 20 字節(jié))跌穗。首部長(zhǎng)度的最大值為1111即15订晌,首部長(zhǎng)度的最大值為15 * 4字節(jié) = 60字節(jié)
。
IP首部長(zhǎng)度
服務(wù)類型
部分蚌吸,優(yōu)先級(jí)標(biāo)志位和服務(wù)類型標(biāo)志位,被路由器用來進(jìn)行流量的優(yōu)先排序砌庄。筆者目前不清楚用意羹唠,暫不做解釋說明。下圖為
Total Length(總長(zhǎng)度)
顯示為001d娄昆,16進(jìn)制的d為13佩微,即13 + 16 = 29。指IP首部和數(shù)據(jù)報(bào)中數(shù)據(jù)之后的長(zhǎng)度萌焰,單位為字節(jié)哺眯。總長(zhǎng)度為16位扒俯,因此數(shù)據(jù)報(bào)的最大長(zhǎng)度為216 - 1 = 65535字節(jié)奶卓。
- 下圖為
標(biāo)識(shí)符
,一個(gè)唯一的標(biāo)識(shí)數(shù)字撼玄,用來識(shí)別一個(gè)數(shù)據(jù)報(bào)或者被分片數(shù)據(jù)包的次序夺姑。目前筆者對(duì)此并不了解,暫不做解釋掌猛。
標(biāo)識(shí)符
-
下圖為
標(biāo)記和分段偏移
盏浙。
標(biāo)記分段偏移 -
標(biāo)記
:用來標(biāo)識(shí)一個(gè)數(shù)據(jù)報(bào)是否是一組分片數(shù)據(jù)包的一部分。-
Flags:0x0000
荔茬,- 其中Reserved bit 為0 占用
1比特
废膘; - DF(Don’t Fragment)為0,占用
1比特
慕蔚;代表不分片丐黄; - MF(More Fragemnt)為0,占用
1比特
坊萝,MF為0孵稽,如果在分片的情況下,代表這是若干分片中的最后一個(gè)十偶; -
分片偏移
為0菩鲜,占用13比特
;0 0000 0000 0000
- 其中Reserved bit 為0 占用
-
分段偏移
:一個(gè)數(shù)據(jù)包是一個(gè)分片惦积,這個(gè)域中的值就會(huì)被用來將數(shù)據(jù)報(bào)以正確順序重新組裝接校。目前筆者對(duì)此并不了解,暫不做解釋。下圖為
Time to live (存活時(shí)間)
蛛勉,用來定義數(shù)據(jù)報(bào)的生存周期鹿寻,以經(jīng)過路由器的條數(shù)/秒數(shù) 進(jìn)行秒數(shù)。目前筆者對(duì)此并不了解诽凌,暫不做解釋毡熏。占用8個(gè)比特
,16進(jìn)制0x40即十進(jìn)制64侣诵。
- 下圖為
協(xié)議
痢法,用來識(shí)別在數(shù)據(jù)包序列中上層協(xié)議數(shù)據(jù)類型。占用8
個(gè)比特杜顺,16進(jìn)制0x11即十進(jìn)制17财搁。代表UDP。
協(xié)議
- 下圖為
首部校驗(yàn)和
躬络,一個(gè)錯(cuò)誤檢測(cè)機(jī)制尖奔,用來確定IP首部的內(nèi)容有沒有被損壞或者篡改桦卒。占用16個(gè)比特
筒严。
首部校驗(yàn)和
- 下圖為
源IP地址
,即發(fā)出數(shù)據(jù)報(bào)的主機(jī)的IP地址殿如。占用32個(gè)比特
膘滨。16進(jìn)制的0x7f代表的127甘凭,0x7f00 0001 表示127.0.0.1
- 下圖為
目的IP地址
,數(shù)據(jù)報(bào)目的地的IP地址火邓。占用32個(gè)比特
丹弱。16進(jìn)制的0x7f代表的127,0x7f00 0001 表示127.0.0.1铲咨。
上述內(nèi)容就是IP的數(shù)據(jù)報(bào)首部的相關(guān)分析躲胳,下邊筆者將給大家介紹下UDP的首部的相關(guān)內(nèi)容:
- 如下圖
UDP的首部
所示,UDP的首部占用64比特纤勒,即8個(gè)字節(jié)
坯苹。
- 下圖表示
UDP的源端口
,占用16比特
摇天。16進(jìn)制為0x f432
即為十進(jìn)制的62514
粹湃。
- 下圖表示
UDP的目標(biāo)端口
,占用16比特
泉坐。16進(jìn)制為0x 4e20
即為十進(jìn)制的20000
为鳄。
UDP的目標(biāo)端口
- 下圖表示
UDP數(shù)據(jù)報(bào)的字節(jié)長(zhǎng)度
,表示數(shù)據(jù)報(bào)的字節(jié)長(zhǎng)度腕让。長(zhǎng)度占用UDP首部16比特
孤钦。16進(jìn)制為0x 0009
即為十進(jìn)制的9
(因?yàn)閁DP首部長(zhǎng)度占8個(gè)字節(jié),加上傳輸了一個(gè)數(shù)據(jù)'A'占用1個(gè)字節(jié),共9字節(jié))偏形。
- 下圖表示
UDP數(shù)據(jù)報(bào)的校驗(yàn)和
静袖,用來確保UDP首部和數(shù)據(jù)到達(dá)時(shí)的完整性。校驗(yàn)和占用UDP首部16比特
俊扭,16進(jìn)制為0x fe1c
队橙。目前筆者對(duì)這個(gè)值并不了解,暫不做解釋萨惑。
- 最后喘帚,傳輸?shù)?code>數(shù)據(jù),包含被UDP封裝進(jìn)去的數(shù)據(jù)咒钟,包含應(yīng)用層協(xié)議頭部和用戶發(fā)出的數(shù)據(jù),我們傳輸?shù)?A'若未,如下圖朱嘴,顯示為16進(jìn)制的0x41即十進(jìn)制的65。
傳輸?shù)臄?shù)據(jù)
參考內(nèi)容:
- Wireshark數(shù)據(jù)包實(shí)戰(zhàn)講解
- https://www.ibm.com/support/knowledgecenter/en/SSLTBW_2.3.0/com.ibm.zos.v2r3.halc001/ipcicint_protocol.htm
- https://www.iana.org/assignments/address-family-numbers/address-family-numbers.xhtml
- https://python3-cookbook.readthedocs.io/zh_CN/latest/c11/p03_creating_udp_server.html
了解更多iOS及相關(guān)新技術(shù)粗合,請(qǐng)關(guān)注我們的公眾號(hào):
關(guān)注我們的途徑有:
QiShare(簡(jiǎn)書)
QiShare(掘金)
QiShare(知乎)
QiShare(GitHub)
QiShare(CocoaChina)
QiShare(StackOverflow)
QiShare(微信公眾號(hào))
推薦文章:
iOS 多線程之GCD
iOS 多線程之NSOperation
iOS 多線程之NSThread
iOS Winding Rules 纏繞規(guī)則
iOS 簽名機(jī)制
iOS 掃描二維碼/條形碼
奇舞周刊