From 04bb5d26c7e068727af08dfd87efcae1e3c61938 Mon Sep 17 00:00:00 2001 From: asahi Date: Sat, 25 Jan 2025 20:20:28 +0800 Subject: [PATCH] =?UTF-8?q?=E9=98=85=E8=AF=BBtcp/ip=20ip=E5=8D=8F=E8=AE=AE?= =?UTF-8?q?=E6=96=87=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tcpip/tcp_ip协议.md | 166 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 165 insertions(+), 1 deletion(-) diff --git a/tcpip/tcp_ip协议.md b/tcpip/tcp_ip协议.md index 405d6bf..abff205 100644 --- a/tcpip/tcp_ip协议.md +++ b/tcpip/tcp_ip协议.md @@ -16,10 +16,15 @@ TCP/IP协议族通常被认作是四层协议系统,每层分别负责不同 ### ipv4地址 ipv4地址大小为4字节,其分类如下所示: - A类: 0~127.xxx.xxx.xxx (第一bit为0) + - A类地址组成为`0` + 7bit `net id` + 24bit `host id` - B类: 128~191.xxx.xxx.xxx (前两位bit为10) + - B类地址组成为`10` + 14bit `net id` + 24bit `host id` - C类: 192~223.xxx.xxx.xxx (前三位bit为110) + - `110` + 21bit `net id` + 8bit `host id` - D类:224~239.xxx.xxx.xxx (前四位bit为1110) + - `1110` + 28bit `multicast group id` - E类:240~255.xxx.xxx.xxx (前五位bit为11110) + - `1111` + 28bit `reserved for future use` ### 协议层封装 当应用向网络中发送数据时,数据被送入协议栈中,从上到下,从应用层一直到数据链路层,每层协议都会为上一层提交的数据添加首部或尾部信息,并且将修改后的数据传递给下一层。 @@ -108,6 +113,165 @@ RFC 894和RFC 1042对数据帧长度有限制,数据部分长度最多不能 ip协议为tcp/ip中最为核心的协议,TPC/UDP/ICMP/IGMP数据都以ip数据报的形式进行发送。 ### IP协议特性 -### +#### 不可靠 ip协议是不可靠的,其并不保证传输的数据被成功送达目标端。如果在ip数据包发送途中,某个路由器暂时用完缓冲区,那么ip协议存在简单的错误处理算法:丢弃该ip数据报,并且向信源段发送ICMP消息报。 +#### 无连接(connectionless) +`无连接`代表ip数据报并不维护任何状态信息,每个数据报的处理是相互独立的。故而,`ip数据报可以不按发送的顺序进行接收`。 + +> 例如,发送端向接收端发送了两个连续的数据报(先发送A再发送B),每个数据报都会独立的进行路由选择,`数据报B可能和数据报A选择不同的路线,故而数据报B可能在数据报A之前到达`。 + +### Ip首部 +ip首部的格式如下所示: + + +#### 首部各字段含义 +##### 版本 +版本长度为4bit,代表ip协议版本号,ipv4场景下该值为4 +##### 首部长度 +首部长度指首部占32bit字的数目,包括`选项`。首部长度占4bit,故而ip协议首部最长为`(2^4-1) * (32/8) bytes = 15 * 4 bytes = 60bytes`。 + +对于普通ip数据报(没有任何选项),其首部长度为20字节,故而首部长度的值为`20 / 4 = 5`。 + +##### 服务类型(TOS) +TOS字段长度为8位,其组成如下: +- `优先权`子字段:3bit,现在会被忽略 +- `TOS`子字段:4bit +- 未用位:1bit,该位目前没有被使用,但是必须置为0 + +TOS子字段其4bit分别代表如下含义:最小时延、最大吞吐量、最高可靠性、最小费用。其4bit中最多只能有一bit被置为1,如果4bit均位0,则代表是一般服务。 + +> 目前,`绝大多数tcp/ip实现都不支持TOS特性`. + +##### 总长度 +总长度指整个ip数据报的长度,单位为字节。例如用首部长度和总长度字节,就能得知ip数据报中内容起始位置和长度。 + +总长度字段,其长度为16位,故而ip数据报最大长度为`65535`字节。但是,受数据链路层协议MTU影响,当ip数据报被分片时,总长度的值也会随着分片而变化。 + +> 而且,由于数据链路层协议拥有传输数据的最小长度限制(例如以太网协议其数据最小长度为46字节)。而ip数据报其长度可能小于46字节。 +> +> 当ip数据报大小小于46字节时,以太网协议会对不足46字节的部分进行填充,故而,总长度字段能够实标识该数据报的实际大小,去除被以太网协议填充的字节。 + +##### 标识 +标识字段为16bit,其会唯一标识主机发送的每一份数据报,通常每发送一份报文,其值会加一。 + +##### 标志字段和位偏移字段 +标志字段和位偏移字段和分片操作有关,分别为3bit和13bit。 + +##### TTL +TTL字段设置了数据报可以经过的最多路由器个数,其指定了数据报的生存时间。`TTL字段的长度为8bit`。 + +TTL字段的初始值由源主机及逆行设置,通常为32或64。每当数据报经过一个路由器的处理,那么ttl字段的值就会减1。`当ttl字段的值为1时,该数据报将会被丢弃,并发送ICMP`报文来通知源主机。 + +##### 协议 +协议字段长度为8 bit,可以用于标识IP协议的上层协议。通过协议字段,可以实现对ip协议的分用。 + +##### 首部校验和 +首部校验和字段长度为16bit,其根据ip首部计算校验和码,并不对首部后的数据进行计算。 + +关于数据的校验和,其在上层TCP,UDP,ICMP,IGMP协议,协议首部中均含有`同时覆盖首部和数据内容的校验和码`。 + +> 在计算首部校验和时,首先将校验和字段设置为0,之后对首部中每个16bit字进行二进制反码求和,并将结果保存到校验和字段中。 +> +> 接收方在接收到数据报后,会对首部每个16bit进行二进制反码求和,并且要求计算结果全为1。如果校验错误,那么ip协议会要求丢弃接收到的数据报,但是不生成差错报文,由上层协议发现丢失的报文并进行重传。 + +> 在路由器在针对ip报文进行转发时,通常需要将ip数据报的ttl减一,故而其需要对ip首部校验和的值进行增加(并不需要重算整个ip首部的校验和). + +##### 源ip地址和目标ip地址 +每个ip数据报都包含源ip地址和目标ip地址,均为4字节32bit。 + +##### 选项 +最后,选项字段是一个可变长度的可选信息。这些选项很少被使用,也并非所有的主机和路由器都支持这些选项。 + +选项字段通常以32bit作为界限,在必要时候会填充0,保证ip首部长度始终为32bit(4字节)的整数倍。 + +### ip路由选择 +通常来说,当目标主机和源主机位于同一个子网内时,ip数据报可以直接发送到目标主机。但是,当目标主机和源主机跨网络通信时,源主机则是将ip数据报发送给默认路由器,并由路由器来转发该数据报。 + +IP发送数据报场景如下: +- 从上层TCP, UDP, ICMP, IGMP中接收数据报并进行发送 +- 从一个网络接口接收数据报并进行发送(转发数据报) + +ip层在内存中拥有一个路由表,当接收到数据报(从上层协议或从网络接口)时,会搜索该路由表, +- 如果数据报来源为某个接口时,首先检查目标ip地址是否为本机ip地址之一或广播ip地址 + - 如果是,数据报则被送到ip首部中协议字段所定义的协议模块进行处理; + - 如果不是上述地址之一,则处理逻辑如下 + - 如果ip层被设置为路由器功能,则对数据报进行转发 + - 如果ip层未被设置为路由器功能,则丢弃该数据报 + +> 故而未被设置为路由器功能的主机,在网络接口接收到ip数据报时,首先会判断该ip数据报是否目标地址为本机的ip或广播(ip数据报是否是发送给自己的)。如果是则传递给上层协议模块;如果不是则丢弃该ip数据报 + +路由表每一条记录都包含如下信息: +- 目标ip地址:可以是主机地址,也可以是网络地址 +- 下一跳路由器的ip地址,或是位于直接相连网络中的ip地址 +- 标志:标识目的ip地址是主机还是网络 +- 指定数据报应该被传输给哪个网络接口(不同的网络接口连接不同的子网,路由表即使将指定ip地址的请求路由到指定的网络接口) + +ip路由选择是逐跳(hop-by-hop)进行的。 + +ip路由选择主要执行如下逻辑: +- 搜索ip路由表,找到能够和目的ip完全匹配的条目,如果能找到,发送 +- 搜索路由表,找到能与目的网络号匹配的条目,如果找到,发送 +- 搜索路由表,找到default条目,发送 + +如果上述尝试都失败,那么该数据报将无法被传达,会向生成数据报的应用程序发送`主机不可达`或`网络不可达`的错误。 + +### 子网 +对于A类或B类地址,其分别能容纳`2^24-2`或`2^16-2`数量的主机,同一网络中并不需要这么多主机,故而通常会建立子网,将host id分割为子网号和主机号,示例如下。 + +#### 组建子网示例 +B类地址组建子网示例如下: +- 网络号: 16位 (`01` + 14bit) +- 子网号:8位 +- 主机号:8位 + +上述示例中,将16bit host id中的8位划分给子网,8位划分给主机号,故而允许有254个子网和254台主机(全0或全1地址无效)。 + +> 在根据host id划分子网和主机位数时,并不要求以字节划分,故而,16位host id可以划分4bit给子网,12bit给主机,故而能拥有14个子网,每个子网最多拥有16382台主机 + +### 子网掩码 +子网掩码用于标识host id中有多少bit用于子网号,有多少bit用于主机号。和ip地址类似,子网掩码也是32bit大小,含义如下: +- 分配给net id和子网号的bit值为1 +- 分配给主机号的bit值为0 + +示例如下: + +假设一个B类地址,`172.19.23.153`,其子网掩码为`255,255.255.0`,代表16bit的host id中,有8位被分配给子网,8位被分配给主机。 + +### endianness +endianness代表字节在内存中的排列顺序,在不同计算机操作系统中,endianness可能有所不同。故而,在不同主机通过网络进行数据交换时,必须通过相同的endianness进行数据的发送和接收。 + +endianness通过存在两种格式:`big endian`和`little endian`: +- big endian:首先存储MSB,即MSB位于内存地址较低的字节 +- little endian:首先存储LSB,即LSB位于内存地址较低的字节 + +#### big endian +在big endian system中, `most significant byte`(MSB)存储在内存的低位地址上。例如,对于32 bit的integer `0x12345678`,其在big endian system中的存储顺序如下: +``` +Address: 00 01 02 03 +Data: 12 34 56 78 +``` +其中,`0x12`为MSB,存储在内存最低位地址`00`上,而`0x78`则是存储在最高位地址`03`上。 + +#### little endian +在little-endian system中,`least significant byte`(LSB)存储在内存的较低位地址上。例如,对于32 bit的integer`0x12345678`,其在little endian system中存储顺序如下: +``` +Address: 00 01 02 03 +Data: 78 56 34 12 +``` +其中,`0x12`位MSB,其存储在最高位地址上`03`上 + + +#### MSB & LSB +MSB & LSB的概念可以参照如下十进制示例。 + +> 对于10进制数`2984`,将其个位修改为`5`会导致整体数值加1,而将千位`2`改为`3`则将导致整体数值增加`1000`,故而,可看作千位相较于个位`more significant`。 + +MSB和LSB的定义如下: +- MSB: The byte that holds the highest position value +- LSB: The byte that holds the lowest position value + +#### 网络字节传输顺序 +网络字节传输中,通常都按照`big endian`字节序来进行传输。 + +操作系统中,`unbuntu`和`windows`都采用`little endian`。