[toc]
传输层功能
封装数据包
对发送数据进行封装,一个一个按顺序进行发送,保证数据包完整准确——TCP协议、UDP协议
定义端口
定义端口的概念,可以寻找到对应的应用程序,从而发给对应的应用程序进行数据处理,如QQ——→QQ
TCP协议
TCP头部结构
TCP(Transmission Control Protocol)传输控制协议,对数据的传输进行一定的控制
TCP连接实现过程
HTTP、HTTPS协议基于TCP协议实现Client—Server交互,只有先实现TCP的交互和连接,才能进行HTTP、HTTPS协议的交互。
TCP三次握手建立连接
消息属性
- 序号- seq (sequence number):由于TCP数据包过大,对其进行分段,每一段记为1、2、3、4……,以便之后按顺序重组。设客户端发送来的一个数据包seq = x
- 确认号 - ack (acknowledge number):存在于确认消息里,依据序号(seq)来编写——ack(确认号) = seq(序号) + 1 = 1 +1 =2,这表示
- 服务器期望确认收到seq = 1的数据包
- 服务器期望收到的下一个包的序号的seq = 2
- 标志位:称为状态控制码(code control flag),说明了TCP数据包的类型,共计有6个标志位,各占1位(bit),重点是以下4个标志位
- ACK:即acknowledge,确认位——
- 1:表示此消息是一个确认消息:如服务器返回给客户端的消息
- 0:即说明此消息不是一个确认消息
- RST:reset,重置位
- 1:表示这个消息是一个释放连接的消息,如TCP连接出现错误(主机服务器崩溃),就断开连接,以请求重新建立连接
- 0:即说明此消息不是一个要释放连接的消息
- SYN:synchronous,同步位
- 1:
- 表示这个消息是一个发起连接的消息,比如客户端请求发起一个连接时首先发送的消息
- 确认接受连接消息:当服务器决定接受连接时,其返回的消息中SYN位也应置为1
- 0:即不符合上述两种情况时,消息的SYN位置为0
- 1:
- FIN:final,终止位
- 1:表示这个发送报文结束、完毕,要释放这个连接,即意味着TCP四次挥手断开连接要开始了
- 0:即不要求释放连接
- ACK:即acknowledge,确认位——
三次握手过程
简要

详细

TCP 三次握手,其实就是建立一个 TCP 连接,客户端与服务器交互需要 3 个数据包。握手的主要作用就是为了确认双方的接收和发送能力是否正常,初始序列号,交换窗口大小以及 MSS 等信息。
- 第一次握手:客户端发送
SYN报文,并进入SYN_SENT状态,等待服务器的确认; - 第二次握手:服务器收到
SYN报文,需要给客户端发送ACK确认报文,同时服务器也要向客户端发送一个SYN报文,所以也就是向客户端发送SYN + ACK报文,此时服务器进入SYN_RCVD状态; - 第三次握手:客户端收到
SYN + ACK报文,向服务器发送确认包,客户端进入ESTABLISHED状态。待服务器收到客户端发送的ACK包也会进入ESTABLISHED状态,完成三次握手。
三次握手的意义——二次握手可以吗
问:为什么 TCP 采用三次握手,二次握手可以吗?
我们可以从几个方面来解释:
(一)确认双方的收发能力
TCP 建立连接之前,需要确认客户端与服务器双方的收包和发包的能力。
1. 第一次握手:客户端发送网络包,服务端收到了。这样服务端就能得出结论:客户端的发送能力、服务端的接收能力是正常的。
2. 第二次握手:服务端发包,客户端收到了。这样客户端就能得出结论:服务端的接收、发送能力,客户端的接收、发送能力是正常的。不过此时服务器并不能确认客户端的接收能力是否正常。
3. 第三次握手:客户端发包,服务端收到了。这样服务端就能得出结论:客户端的接收、发送能力正常,服务器自己的发送、接收能力也正常。
所以,只有三次握手才能确认双方的接收与发送能力是否正常。
(二)序列号可靠同步
如果是两次握手,服务端无法确定客户端是否已经接收到了自己发送的初始序列号,如果第二次握手报文丢失,那么客户端就无法知道服务端的初始序列号,那 TCP 的可靠性就无从谈起。
(三)阻止重复历史连接的初始化
客户端由于某种原因发送了两个不同序号的 SYN 包,我们知道网络环境是复杂的,旧的数据包有可能先到达服务器。如果是两次握手,服务器收到旧的 SYN 就会立刻建立连接,那么会造成网络异常。
如果是三次握手,服务器需要回复 SYN+ACK 包,客户端会对比应答的序号,如果发现是旧的报文,就会给服务器发 RST 报文,直到正常的 SYN 到达服务器后才正常建立连接。
所以三次握手才有足够的上下文信息来判断当前连接是否是历史连接。
(四)安全问题
我们知道 TCP 新建连接时,内核会为连接分配一系列的内存资源,如果采用两次握手,就建立连接,那会放大 DDOS 攻击的。
TCP 作为一种可靠传输控制协议,其核心思想:既要保证数据可靠传输,又要提高传输的效率,而三次握手恰好可以满足以上两方面的需求!
初始序列号(ISN)的引入
问:ISN 代表什么?意义何在?ISN 是固定不变的吗?ISN为何要动态随机?
ISN 是什么?
答:ISN 全称是 Initial Sequence Number,是 TCP 发送方的字节数据编号的原点,告诉对方我要开始发送数据的初始化序列号。
TCP在开始传输数据前,客户端和服务器需要随机生成自己的初始序列号(initial sequence number-ISN),然后通过三次握手进行交换确认。
ISN 是固定不变的吗?
答:ISN 如果是固定的,攻击者很容易猜出后续的确认序号,为了安全起见,避免被第三方猜到从而发送伪造的 RST 报文,因此 ISN 是动态生成的。
Wireshark抓包详解三次握手
点击Wireshark开始抓包后访问某个HTTP/S的网址:www.pinglinag.gov.cn

ping命令查看该服务器IP

在Wireshark过滤器中设置为tcp则得到许多TCP的数据包

Wireshark中选择Destination为上面ping中所示的61.78.180.240的TCP数据包——右键追踪流——TCP流,就能把这一个连接的所有数据包过滤出来

查看第一个数据包,数据链路层注意源目MAC地址,网络层注意源目IP,传输层注意协议、端口,注意我们所关心的几个字段——这是一个请求TCP连接的数据包

查看第二个数据包

查看第三个数据包

以上三个数据包即TCP三次握手,已经建立连接,第四个数据包可以看到就是HTTP协议的数据包

TCP四次挥手断开连接
四次挥手过程
简要

注意:“第一次挥手”的ACK标志位必为1,因为TCP是可靠连接,在发起释放连接请求前必然接收到了上一条消息,于是在“第一次挥手”的ACK标志位置为1,以表示确认收到了上一条消息。
详细

- 第一次挥手。客户端发起
FIN包(FIN = 1),客户端进入FIN_WAIT_1状态。TCP 规定,即使FIN包不携带数据,也要消耗一个序号。 - 第二次挥手。服务器端收到
FIN包,发出确认包ACK(ack = u + 1),并带上自己的序号 seq=v,服务器端进入了CLOSE_WAIT状态。这个时候客户端已经没有数据要发送了,不过服务器端有数据发送的话,客户端依然需要接收。客户端接收到服务器端发送的ACK后,进入了FIN_WAIT_2状态。 - 第三次挥手。服务器端数据发送完毕后,向客户端发送
FIN包(seq=w ack=u+1),半连接状态下服务器可能又发送了一些数据,假设发送 seq 为 w。服务器此时进入了LAST_ACK状态。 - 第四次挥手。客户端收到服务器的
FIN包后,发出确认包(ACK=1,ack=w+1),此时客户端就进入了TIME_WAIT状态。注意此时 TCP 连接还没有释放,必须经过2*MSL后,才进入CLOSED状态。而服务器端收到客户端的确认包ACK后就进入了CLOSED状态,可以看出服务器端结束 TCP 连接的时间要比客户端早一些。
四次握手的意义
问:为什么建立连接握手三次,关闭连接时需要是四次呢?
答:其实在 TCP 握手的时候,接收端发送 SYN+ACK 的包是将一个 ACK 和一个 SYN 合并到一个包中,所以减少了一次包的发送,三次完成握手。
对于四次挥手,因为 TCP 是全双工通信,在主动关闭方发送 FIN 包后,接收端可能还要发送数据,不能立即关闭服务器端到客户端的数据通道,所以也就不能将服务器端的 FIN 包与对客户端的 ACK 包合并发送,只能先确认 ACK,然后服务器待无需发送数据时再发送 FIN 包,所以四次挥手时必须是四次数据包的交互。
问:为什么TIME_WAIT 状态需要经过 2MSL 才能返回到 CLOSE 状态?
答:MSL 指的是报文在网络中最大生存时间。在客户端发送对服务器端的 FIN 的确认包 ACK 后,这个 ACK 包是有可能不可达的,服务器端如果收不到 ACK 的话需要重新发送 FIN 包。
所以客户端发送 ACK 后需要留出 2MSL 时间(ACK 到达服务器 + 服务器发送 FIN 重传包,一来一回)等待确认服务器端确实收到了 ACK 包。
也就是说客户端如果等待 2MSL 时间也没有收到服务器端的重传包 FIN,说明可以确认服务器已经收到客户端发送的 ACK。
还有第 2 个理由,避免新旧连接混淆。
在客户端发送完最后一个 ACK 报文段后,在经过 2MSL 时间,就可以使本连接持续的时间内所产生的所有报文都从网络中消失,使下一个新的连接中不会出现这种旧的连接请求报文。
你要知道,有些自作主张的路由器会缓存 IP 数据包,如果连接重用了,那么这些延迟收到的包就有可能会跟新连接混在一起。
Wireshark抓包详解四次挥手
真机抓包的时候发现实际四次握手的第二次和第三次貌似是合并在一起了,并没有分成两次来发送(seq和ack的值是没问题的),后面查了下资料这种情况不仅发生在tcp,可能在其他的协议中也会发生,比如说ssl,在握手的过程中理论上的交互包有十来个,但是实际抓的可能才几个,这种现象是协议开发者为了提高效率而做的有意的合并,所以理论还是要结合实践的

第一个数据包:

第二个数据包:

第三个数据包:

参考
知乎:wireshark抓包分析四次挥手,却只能抓到三次,有没有办法抓到四次?
基于TCP的协议
- HTTP/S协议
- FTP(文件传输协议)
UDP协议
UDP(User Datagram Protocol)用户数据协议
UDP协议头部结构

UDP——无连接传输协议
UDP特性
- UDP不会建立连接
- UDP不存在序号、确认号、标志位,是不可靠协议——允许出现丢包、出错;而TCP有重传机制
- 优点:
- 速度很快
- 资源消耗特别小
UDP适用场景
- 不需要可靠机制,只要求速度:如流媒体、多媒体游戏、网络电话
- 资源消耗特别小
基于UDP的协议
- DNS(域名解析协议)
- SNMP(简单网络管理协议)
- DHCP(动态获取IP)
- RIP(动态路由)
WIreshark抓包详解UDP协议
由于DNS协议基于UDP,因此可以触发DNS流量来抓UDP的数据包,命令行ping命令,ping某个域名时就会调用DNS协议解析该域名的IP地址,即可触发DNS流量。
开启抓包后,ping www.sina.com

Wireshark过滤设置为dns过滤报文

查看发送数据包

查看接收数据包

TCP协议和UDP协议的区别
| 特征点 | TCP协议 | UDP协议 |
|---|---|---|
| 是否连接 | 面向连接 | 面向非连接 |
| 传输可靠性 | 可靠 | 会丢包,不可靠 |
| 应用场景 | 传输数据量大 | 传输量小 |
| 速度 | 慢 | 快 |