网络通信协议之 IP、UDP
女主宣言
笔者最近了解了一下Python相关的内容,发现网络编程部分非常容易能够创建一个UDP本地服务器,正好可以用来分析一下UDP的请求和响应。在本篇文章中,笔者将给大家介绍下IP、UDP的部分内容。
PS:丰富的一线技术、多元化的表现形式,尽在“ 360云计算 ”,点关注哦!
OSI、IP、UDP 简介
聊到网络协议,我们常常会想到 OSI (Open System Interconnection 开放式系统互联)七层模型、 TCP/IP 协议簇,它位于OSI、TCP/IP协议簇哪一层等问题。
如下图OSI七层模型及对应的TCP/IP协议簇所示。
-
UDP (User Datagram Protocol 用户数据报协议)位于OSI中的第四层(传输层)。位于TCP/IP协议簇中的第四层(TCP or UDP)。
-
IP (Internet Protocol 网络协议)OSI中的第三层(网络层),位于TCP/IP协议簇中的第三层(IP)。
下图 是OSI七层模型及对应的TCP/IP 协议簇
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.
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服务端代码:
-
终端作为客户端,使用如下代码,UDP客户端代码:
示意图如下:
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
在线进制转换
-
下图是 请求 的示意图,可见数据部分是 0x41 表示的是十进制的65,即’A’的ASCII码。
请求
-
下图是 响应 的示意图,可见数据部分是 0x41424344 表示的是十进制的65 66 67 68,即’ABCD’的ASCII码。
响应
-
下图标识的是 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,占用 1 3比特 ;0 0000 0000 0000
-
分段偏移 :一个数据包是一个分片,这个域中的值就会被用来将数据报以正确顺序重新组装。目前笔者对此并不了解,暂不做解释。
-
下图为 Time to live (存活时间) ,用来定义数据报的生存周期,以经过路由器的条数/秒数 进行秒数。目前笔者对此并不了解,暂不做解释。占用 8个比特 ,16进制0x40即十进制64。
Time to live
Time to li ve
-
下图为 协议 ,用来识别在数据包序列中上层协议数据类型。占用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的数据报首部的相关分析,下边笔者将给大家介绍下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。
传输的数据
参考内容:
Wireshark数据包实战讲解
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