1. OSI模型、TCPIP模型

2. 数据报组成

-
前导字段,也称报头,这是一段方波,用于使收发节点的时钟同步。内容为连续7个字节的0x55。字段和帧起始定界符在MAC收到数据包后会自动过滤掉。
-
帧起始定界符(SFD):用于区分前导段与数据段的,内容为0xD5。
-
MAC地址: MAC地址由48位数字组成,它是网卡的物理地址,在以太网传输的最底层,就是根据MAC地址来收发数据的。部分MAC地址用于广播和多播,在同一个网络里不能有两个相同的MAC地址。PC的网卡在出厂时已经设置好了MAC地址,但也可以通过一些软件来进行修改,在嵌入式的以太网控制器中可由程序进行配置。数据包中的DA是目标地址,SA是源地址。
-
数据包类型:本区域可以用来描述本MAC数据包是属于TCP/IP协议层的IP包、ARP包还是SNMP包,也可以用来描述本MAC数据包数据段的长度。如果该值被设置大于0x0600,不用于长度描述,而是用于类型描述功能,表示与以太网帧相关的MAC客户端协议的种类。
-
数据段:数据段是MAC包的核心内容,它包含的数据来自MAC的上层。其长度可以从0~1500字节间变化。
-
填充域:由于协议要求整个MAC数据包的长度至少为64字节(接收到的数据包如果少于64字节会被认为发生冲突,数据包被自动丢弃),当数据段的字节少于46字节时,在填充域会自动填上无效数据,以使数据包符合长度要求。
-
校验和域:MAC数据包的尾部是校验和域,它保存了CRC校验序列,用于检错。
3. 数据报详解

-
前导字(7B):使接收端的适配器在接收 MAC 帧时能够迅速调整时钟频率,使它和发送端的频率相同。固定,0x55,0x55,0x55,0x55,0x55,0x55,0x55
-
SFD(1B):帧的起始符,为 1 个字节。固定,0xD5
-
网络头(12B)
-
目的MAC(6B):接收帧的网络适配器的物理地址(MAC 地址)
-
源MAC(6B):发送帧的网络适配器的物理地址(MAC 地址)
-
帧类型(2B):上层协议的类型。由于上层协议众多,所以在处理数据的时候必须设置该字段,标识数据交付哪个协议处理。常见0x0800(IP协议)、0x806(ARP协议)
-
-
IPV4头(20B)
-
Version(4b):IP协议实现的版本号,分IPV4和IPV6
-
IHL(4b):报头长度
-
TypeofService(1B):服务类型,4bit的TOS分别代表:最小时延,最大吞吐量,最高可靠性和最小费用。
-
TotalLength(2B):指明整个数据报的长度
-
Identification(2B):用来唯一地标识主机发送的每一份数据报。通常每发一份报文,它的值会加1
-
Flags(4b):标志一份数据报是否要求分段 1460 1500
-
FragmentOffset(12b):如果一份数据报要求分段的话,此字段指明该段偏移距原始数据报开始的位置
-
TimeToLive(1B):生存期,通常为32、64、128等。用来设置数据报最多可以经过的路由器数
-
Protocol(1B):IP层所封装的上层协议类型,ICMP(1)、IGMP(2) 、TCP(6)、UDP(17)
-
HeaderCheckSum(2B):头部校验和
-
SourceIP(4B):源IP地址
-
DestinationIP(4B):目标IP地址
-
Options:可选项字段
-
-
TCP头(20B)
-
SourcePort(2B):源端口号
-
DestinationPort(2B):目标端口号
-
SequenceNumber(4B):在一个TCP连接中传送的字节流中的每一个字节都按顺序编号。整个要传送的字节流的起始序号必须在连接建立时设置。首部中的序号字段值则是指的是本报文段所发送的数据的第一个字节的序号。顺序号字段,用来标识从TCP源端向TCP目标端发送的数据字节流,它表示在这个报文段中的第一个数据字节
-
AckNumber(4B):确认号字段,只有ACK标志为1时,确认号字段才有效。它包含目标端所期望收到源端的下一个数据字节
-
HeaderLengthTCP(1B):头部长度字段
-
Reserve(1B):预留
-
CWR(1b):
-
ECE(1b):
-
URG(1b):表明紧急指针字段有效,表明此报文段中有紧急数据,是高优先级的数据,应尽快发送,不用在缓存中排队。
-
ACK(1b):表示前面的确认号字段是否有效:ACK=1 时表示有效;只有当 ACK=1 时,前面的确认号字段才有效;TCP 规定,连接建立后,ACK 必须为 1
-
PSH(1b):接收方应该尽快将这个报文段交给应用层
-
RST(1b):表示是否重置连接:若 RST=1,说明TCP连接出现了严重错误(如主机崩溃),必须释放连接,然后再重新建立连接
-
SYN(1b):在建立连接时使用,用来同步序号:当 SYN=1,ACK=0 时,表示这是一个请求建立连接的报文段;当 SYN=1,ACK=1时,表示对方同意建立连接;SYN=1时,说明这是一个请求建立连接或同意建立连接的报文;只有在前两次握手中SYN才为1
-
FIN(1b):标记数据是否发送完毕:若FIN=1,表示数据已经发送完成,可以释放连接
-
WindowSize(4B):窗口大小字段,本机期望一次接收的字节数.滑动窗口大小,用来告知发送端接受端的缓存大小,以此控制发送端发送数据的速率,从而达到流量控制。窗口大小是一个16bit字段,因而窗口大小最大为65535。
-
TCPCheckSumTCP(4B):校验和字段
-
UrgentPointer(4B):紧急指针字段,它是一个偏移量,和序号字段中的值相加表示紧急数据最后一个字节的序号
-
Options:可选项字段
-
-
FCS(4B):检测该帧是否出现差错,发送方计算帧的循环冗余码校验(CRC)值,把这个值写到帧里。接收方计算机重新计算 CRC,与 FCS 字段的值进行比较。如果两个值不相同,则表示传输过程中发生了数据丢失或改变。
4. TCP链接

-
三次握手(建立链接)
-
客户端要向服务端发起连接请求,首先客户端随机生成一个起始序列号ISN,那客户端向服务端发送的报文段包含SYN标志位(也就是SYN=1),序列号seq=100。
-
服务端收到客户端发过来的报文后,发现SYN=1,知道这是一个连接请求,于是将客户端的起始序列号100存起来,并且随机生成一个服务端的起始序列号(比如是300)。然后给客户端回复一段报文,回复报文包含SYN和ACK标志(也就是SYN=1,ACK=1)、序列号seq=300、确认号ack=101(客户端发过来的序列号+1)。
-
客户端收到服务端的回复后发现ACK=1并且ack=101,于是知道服务端已经收到了序列号为100的那段报文;同时发现SYN=1,知道了服务端同意了这次连接,于是就将服务端的序列号300给存下来。然后客户端再回复一段报文给服务端,报文包含ACK标志位(ACK=1)、ack=301(服务端序列号+1)、seq=101(第一次握手时发送报文是占据一个序列号的,所以这次seq就从101开始,需要注意的是不携带数据的ACK报文是不占据序列号的,所以后面第一次正式发送数据时seq还是101)。当服务端收到报文后发现ACK=1并且ack=301,就知道客户端收到序列号为300的报文了,就这样客户端和服务端通过TCP建立了连接。
-
-
四次挥手(关闭链接)
-
当客户端的数据都传输完成后,客户端向服务端发出连接释放报文(当然数据没发完时也可以发送连接释放报文并停止发送数据),释放连接报文包含FIN标志位(FIN=1)、序列号seq=1101。需要注意的是客户端发出FIN报文段后只是不能发数据,但是还可以正常收数据;另外FIN报文段即使不携带数据也要占据一个序列号。
-
服务端收到客户端发的FIN报文后给客户端回复确认报文,确认报文包含ACK标志位(ACK=1)、确认号ack=1102(客户端FIN报文序列号1101+1)、序列号seq=2300。此时服务端处于关闭等待状态,不是立马给客户端发FIN报文,这个状态还要持续一段时间,因为服务端可能还有数据没发完,可继续发送。
-
服务端将最后数据(比如50个字节)发送完毕后就向客户端发出连接释放报文,报文包含FIN和ACK标志位(FIN=1,ACK=1)、确认号和第二次挥手一样ack=1102、序列号seq=2350(2300+50)。
-
客户端收到服务端发的FIN报文后,向服务端发出确认报文,确认报文包含ACK标志位(ACK=1)、确认号ack=2351、序列号seq=1102。注意客户端发出确认报文后不是立马释放TCP连接,而是要经过2MSL(最长报文段寿命的2倍时长)后才释放TCP连接。而服务端一旦收到客户端发出的确认报文就会立马释放TCP连接,所以服务端结束TCP连接的时间要比客户端早一些。
-
-
四次挥手?
关闭连接时,客户端向服务端发送 FIN 时,仅仅表示客户端不再发送数据了但是还能接收数据,服务端收到客户端的 FIN 报文时,先回一个 ACK 应答报文,而服务端可能还有数据需要处理和发送的数据,等服务端不再发送数据时,才发送 FIN 报文给客户端来表示同意现在关闭连接。因此是需要四次挥手。
-
第二次和第三次挥手合并?
当被动关闭方即服务端,在 TCP 挥手过程中,「没有数据要发送」并且「开启了 TCP 延迟确认机制」,那么第二和第三次挥手就会合并传输,这样就出现了三次挥手。
-
确认报文后要等2MSL?
要考虑丢包的问题,如果第四次挥手的报文丢失,服务端没收到确认ack报文就会重发第三次挥手的报文,这样报文一去一回最长时间就是2MSL,所以需要等这么长时间来确认服务端确实已经收到了。
-
TCP 延迟确认机制:
-
一般情况下这个时延为200ms
-
当有响应数据要发送时,ACK 会随着响应数据一起立刻发送给对方
-
当没有响应数据要发送时,ACK 将会延迟一段时间,以等待是否有响应数据可以一起发送
-
如果在延迟等待发送 ACK 期间,对方的第二个数据报文又到达了,这时就会立刻发送 ACK
-
-
Timer_Wait
Timer time_wati状态下发出的给被关闭端ack报文后等待时间(30~120s),一般设置一个msl(最长报文寿命)是60s
本文详细解析了OSI模型和TCP/IP模型,介绍了数据报的构成,包括前导字段、帧起始定界符、MAC地址、IP头和TCP头部的各个字段。重点阐述了TCP连接的三次握手和四次挥手过程,以及TCP的延迟确认机制和报文确认策略。
4440

被折叠的 条评论
为什么被折叠?



