1、网络的本质
数据报文是网络运行世界里,具有完整信息的、最小的组成单元,而协议则是数据报文在网络内交互必须遵循的规则。最简单的理解,一个又一个的遵守着网络协议的数据包进行着交换,构成了我们所理解的网络世界。因此掌握了这两者,基本上就可以把握网络运行的本质。
2、网络分层
由于在实际的计算机网络中,两个实体之间的通信情况非常复为了降低通信协议实现的复杂性,而将整个网络的通信功能划分为多个层次(分层描述),每层各自完一定的任务,而且功能相对独立,这样实现起来较容易。
网络系统被分为4/5层(TCP/IP参考模型)或7层(OSI参考模型),每一层都有对应的网络协议完成特定类别的功能。它们相互协作将原始信息进行分层打包(发送过程)和解包(接收过程),以流水线的方式完成复杂的网络传输过程。 应用层俗称7层,传输层俗称4层,IP层俗称3层,数据链路层俗称2层。
3、网络协议
同一通信节点安装的每一层协议依赖并使用下层协议提供的服务,完成特定的功能,再向其上层协议提供服务;相邻上下层协议之间通过接口通信;不同结点的对等层按照对等协议和数据单元实现对等层之间的通信。不同层的数据单元名称也不同,如下图所示:
4、封装与解封装
原始数据包经过每一层都会被该层协议进行改造(封装头尾部、解封头尾部),改造后的数据包被下层协议(发送)或上层协议(接收)识别(通过特点标识如MAC、IP、端口)、改造、传输,最终被目的IP的对等应用接收。
4.1 数据封装
原始数据从上至下添加内容(封装数据),最后传递到物理层变成光电信号进行传输。
4.2 数据解封装
从物理层接收光电信号,从下至上拆除封装数据时每层添加的内容(数据解封装),最后传递到接收数据的应用程序,获得原始数据。
5、数据包格式
以下是学习TCP/IP协议栈的一些主要数据包的格式,关于每个数据包格式的详细作用说明,在以后适当的时候再来进行说明,这里先对网络数据包的格式样子有个概念性的了解即可。
5.1 二层MAC帧
二层即数据链路层,在该层中,数据包称为帧,帧的结构如下图所示:
字段 | 长度 | 含义 |
---|---|---|
DMAC | (6字节) | 目的MAC地址,IPV4为6字节,该字段确定帧的接收者。 |
SMAC | (6字节) | 源MAC地址,IPV4为6字节,该字段标识发送帧的工作站。 |
Type | (2字节) | 协议类型。一般为0x0800,表示封装的是IP协议。 |
Data | 变长 | 数据字段的最小长度必须为46字节以保证帧长至少为64字节,这意味着传输一字节信息也必须使用46字节的数据字段。 如果填入该字段的信息少于46字节,该字段的其余部分也必须进行填充。数据字段的最大长度为1500字节。 |
CRC | (4字节) | 用于帧内后续字节差错的循环冗余检验(也称为FCS或帧检验序列)。 |
1.IFG(Interframe Gap),帧间距,以太网相邻两帧之间的时间断;以太网发送方式是一个帧一个帧发送的,帧与帧之间需要间隙。
2.前同步码和帧开始分界符的作用:其作用是使目的主机接收器时钟与源主机发送器时钟同步。紧接着是帧开始分界符字节“10101011”,用于指示帧的开始。
据RFC894的说明,以太网封装IP数据包的最大长度是1500字节,也就是说以太网最大帧长应该是以太网首部加上1500,再加上7字节的前导同步码和1字节的帧开始定界符,具体就是:7字节前导同步吗+1字节帧开始定界符+6字节的目的MAC+6字节的源MAC+2字节的帧类型+1500+4字节的FCS。
按照上述,最大帧应该是1526字节,但是实际上我们抓包得到的最大帧是1514字节,为什么不是1526字节呢? 原因是当数据帧到达网卡时,在物理层上网卡要先去掉前导同步码和帧开始定界符,然后对帧进行CRC检验,如果帧校验和错,就丢弃此帧。如果校验和正确,就判断帧的目的硬件地址是否符合自己的接收条件(目的地址是自己的物理硬件地址、广播地址、可接收的多播硬件地址等),如果符合,就将帧交“设备驱动程序”做进一步处理。这时我们的抓包软件才能抓到数据, 因此,抓包软件抓到的是去掉前导同步码、帧开始分界符、FCS之外的数据,其最大值是6+6+2+1500=1514。
以太网规定,以太网帧数据域部分最小为46字节,也就是以太网帧最小是6+6+2+46+4=64。除去4个字节的FCS,因此,抓包时就是60字节。当数据字段的长度小于46字节时,MAC子层就会在数据字段的后面填充以满足数据帧长不小于64字节。由于填充数据是由MAC子层负责,也就是设备驱动程序。
以CSMA/CD作为MAC算法的一类LAN称为以太网。CSMA/CD冲突避免的方法:先听后发、边听边发、随机延迟后重发。一旦发生冲突,必须让每台主机都能检测到。关于最小发送间隙和最小帧长的规定也是为了避免冲突。
考虑如下的情况,主机发送的帧很小,而两台冲突主机相距很远。在主机A发送的帧传输到B的前一刻,B开始发送帧。这样,当A的帧到达B时,B检测到冲突,于是发送冲突信号。假如在B的冲突信号传输到A之前,A的帧已经发送完毕,那么A将检测不到冲突而误认为已发送成功。由于信号传播是有时延的,因此检测冲突也需要一定的时间。这也是为什么必须有个最小帧长的限制。
按照标准,10Mbps以太网采用中继器时,连接的最大长度是2500米,最多经过4个中继器,因此规定对10Mbps以太网一帧的最小发送时间为51.2微秒。这段时间所能传输的数据为512位,因此也称该时间为512位时。这个时间定义为以太网时隙,或冲突时槽。512位=64字节,这就是以太网帧最小64字节的原因。
512位时是主机捕获信道的时间。如果某主机发送一个帧的64字节仍无冲突,以后也就不会再发生冲突了,称此主机捕获了信道。
由于信道是所有主机共享的,如果数据帧太长就会出现有的主机长时间不能发送数据,而且有的发送数据可能超出接收端的缓冲区大小,造成缓冲溢出。为避免单一主机占用信道时间过长,规定了以太网帧的最大帧长为1500。
100Mbps以太网的时隙仍为512位时,以太网规定一帧的最小发送时间必须为5.12μs。
1000Mbps以太网的时隙增至512字节,即4096位时,4.096μs。
帧示例:
5.2 三层IP报文
三层即网络层,在该层中数据包称为IP报文,IP报文的结构如下图所示:
字段 | 长度 | 含义 |
---|---|---|
Version | (4比特) | 4:表示为IPV4; 6:表示为IPV6。 |
IHL | (4比特) | 首部长度,如果不带Option字段,则为20,最长为60,该值限制了记录路由选项。以4字节为一个单位。 |
Type of Service | (8比特) | 服务类型。只有在有QoS差分服务要求时这个字段才起作用。 |
Total Length | (16比特) | 总长度,整个IP数据报的长度,包括首部和数据之和,单位为字节,最长65535,总长度必须不超过最大传输单元MTU。 |
Identification | (16比特) | 标识,主机每发一个报文,加1,分片重组时会用到该字段。 |
Flags | (3比特) | 标志位: IP Flag字段格式 Bit 0: 保留位,必须为0。 Bit 1: DF(Don't Fragment),能否分片位,0表示可以分片,1表示不能分片。 Bit 2: MF(More Fragment),表示是否该报文为最后一片,0表示最后一片,1代表后面还有。 |
Fragment Offset | (12比特) | 片偏移:分片重组时会用到该字段。表示较长的分组在分片后,某片在原分组中的相对位置。以8个字节为偏移单位。 |
Time to Live | (8比特) | 生存时间:可经过的最多路由数,即数据包在网络中可通过的路由器数的最大值。 |
Protocol | (8比特) | 协议:下一层协议。指出此数据包携带的数据使用何种协议,以便目的主机的IP层将数据部分上交给哪个进程处理。 常见值: 0: 保留Reserved 1: ICMP, Internet Control Message [RFC792] 2: IGMP, Internet Group Management [RFC1112] 6: TCP Transmission Control Protocol [RFC793] 17: UDP User Datagram Protocol [RFC768] 47: GRE (General Routing Encapsulation) 50: ESP Encap Security Payload [RFC2406] 51: AH (Authentication Header) [RFC2402] 89: OSPF (OSPF Version 2) [RFC 1583] 112: VRRP (Virtual Router Redundancy Protocol) [RFC3768] 115: L2TP (Layer Two Tunneling Protocol) |
Header Checksum | (16比特) | 首部检验和,只检验数据包的首部,不检验数据部分。这里不采用CRC检验码,而采用简单的计算方法。 |
Source Address | (32比特) | 源IP地址。 |
Destination Address | (32比特) | 目的IP地址。 |
Options | 可变 | 选项字段,用来支持排错,测量以及安全等措施。选项字段长度可变,从1字节到40字节不等,取决于所选项的功能。 |
Padding | 可变 | 填充字段,全填0。 |
报文示例:
5.3 四层TCP段
四层即传输层,在该层中数据包称为段,TCP段的结构如下图所示:
字段 | 长度 | 含义 |
---|---|---|
Source Port | (16比特) | 源端口,标识哪个应用程序发送。 |
Destination Port | (16比特) | 目的端口,标识哪个应用程序接收。 |
Sequence Number | (32比特) | 序号字段。TCP链接中传输的数据流中每个字节都编上一个序号。序号字段的值指的是本报文段所发送的数据的第一个字节的序号。 |
Acknowledgment Number | (32比特) | 确认号,是期望收到对方的下一个报文段的数据的第1个字节的序号,即上次已成功接收到的数据字节序号加1。只有ACK标识为1,此字段有效。 |
Data Offset | (4比特) | 数据偏移,即首部长度,指出TCP报文段的数据起始处距离TCP报文段的起始处有多远,以32比特(4字节)为计算单位。最多有60字节的首部,若无选项字段,正常为20字节。 |
Reserved | (6比特) | 保留,必须填0。 |
URG | (1比特) | 紧急指针有效标识。它告诉系统此报文段中有紧急数据,应尽快传送(相当于高优先级的数据)。 |
ACK | (1比特) | 确认序号有效标识。只有当ACK=1时确认号字段才有效。当ACK=0时,确认号无效。 |
PSH | (1比特) | 标识接收方应该尽快将这个报文段交给应用层。接收到PSH = 1的TCP报文段,应尽快的交付接收应用进程,而不再等待整个缓存都填满了后再向上交付。 |
RST | (1比特) | 重建连接标识。当RST=1时,表明TCP连接中出现严重错误(如由于主机崩溃或其他原因),必须释放连接,然后再重新建立连接。 |
SYN | (1比特) | 同步序号标识,用来发起一个连接。SYN=1表示这是一个连接请求或连接接受请求。 |
FIN | (1比特) | 发端完成发送任务标识。用来释放一个连接。FIN=1表明此报文段的发送端的数据已经发送完毕,并要求释放连接。 |
Window | (16比特) | 窗口:TCP的流量控制,窗口起始于确认序号字段指明的值,这个值是接收端正期望接收的字节数。窗口最大为65535字节。 |
Checksum | (16比特) | 窗口:TCP的流量控制,窗口起始于确认序号字段指明的值,这个值是接收端正期望接收的字节数。窗口最大为65535字节。 |
Urgent Pointer | (16比特) | 紧急指针,只有当URG标志置1时紧急指针才有效。TCP的紧急方式是发送端向另一端发送紧急数据的一种方式。紧急指针指出在本报文段中紧急数据共有多少个字节(紧急数据放在本报文段数据的最前面)。 |
Options | 可变 | 选项字段。TCP协议最初只规定了一种选项,即最长报文段长度(数据字段加上TCP首部),又称为MSS。MSS告诉对方TCP“我的缓存所能接收的报文段的数据字段的最大长度是MSS个字节”。 新的RFC规定有以下几种选型:选项表结束,无操作,最大报文段长度,窗口扩大因子,时间戳。 窗口扩大因子:3字节,其中一个字节表示偏移值S。新的窗口值等于TCP首部中的窗口位数增大到(16+S),相当于把窗口值向左移动S位后获得实际的窗口大小。 时间戳:10字节,其中最主要的字段是时间戳值(4字节)和时间戳回送应答字段(4字节)。 选项确认选项: |
Padding | 可变 | 填充字段,用来补位,使整个首部长度是4字节的整数倍。 |
data | 可变 | TCP负载。 |
TCP报文示例:
三次握手:
数据传输:
HTTP长连接用于保持连接的数据包:
重复ACK:
重传:
乱序:
窗口更新:
5.4 四层UDP段
四层即传输层,在该层中数据包称为段,UDP段的结构如下图所示:
字段 | 长度 | 含义 |
---|---|---|
Source Port | (2字节) | 标识哪个应用程序发送(发送进程)。 |
Destination Port | (2字节) | 标识哪个应用程序接收(接收进程)。 |
Length | (2字节) | UDP首部加上UDP数据的字节数,最小为8。 |
Checksum | (2字节) | 覆盖UDP首部和UDP数据,是可选的。 |
data octets | 变长 | UDP负载,可选的。 |
UDP报文示例:
5.5 七层HTTP数据
http请求头报文示例:
http响应头报文示例:
5.6 七层DNS数据
DNS请求报文示例:
DNS响应报文示例: