【网络基础之五】传输层协议与TCP三次握手原理

160 阅读10分钟

一、传输层协议

TCP/IP(Transmission Control Protocol/Internet Protocol 传输控制协议/因特网互联协议)是一个协议栈(Protocol Stack),包括TCP、IP、UDP、ICMP、RIP、TELNET、FTP、SMTP、ARP等许多协议。

  • TCP向上层提供面向连接的可靠服务 ,TCP是可靠的进程到进程通信的协议
  • TCP提供全双工服务,即数据可以在同一时间双向传输
  • UDP向上层提供无连接不可靠服务。

1.TCP/IP模型

a4401fe90c60f511bcfc94dcfe2f769.jpg

2.TCP协议

TCP是一种面向连接的协议,提供可靠的数据传输。它使用三次握手建立连接,通过序号和确认应答来保证数据的完整性和顺序性。TCP还支持流量控制和拥塞控制,以调节数据传输的速率和处理网络拥塞。

  • 工作在传输层
  • 面向连接协议
  • 全双工协议
  • 半关闭
  • 错误检查
  • 将数据打包成段,排序
  • 确认机制
  • 数据恢复,重传
  • 流量控制,滑动窗口

3.TCP报文格式

e806f923ecc82f61d0cecafe438c213.jpg

端口号:用来标识同一台计算机的不同的应用进程。

  • 源端口:源端口和IP地址的作用是标识报文的返回地址。
  • 目的端口:端口指明接收方计算机上的应用程序接口。
  • TCP报头中的源端口号和目的端口号同IP数据报中的源IP与目的IP唯一确定一条TCP连接。

序列号(seq): 表示本报文段所发送数据的第一个字节的编号。在TCP连接中所传送的字节流的每一个字节都会按顺序编号。由于序列号由32位表示,所以每2^32个字节,就会出现序列号回绕,再次从0 开始。

确认号(ack) :表示接收方期望收到发送方下一个报文段的第一个字节数据的编号。也就是告诉发送方:我希望你(指发送方)下次发送的数据的第一个字节数据的编号为此确认号,传输是否有问题?

数据偏移/首部长度:表示TCP报文段的首部长度,共4位,由于TCP首部包含一个长度可变的选项部分,需要指定这个TCP报文段到底有多长。它指出 TCP 报文段的数据起始处距离 TCP 报文段的起始处有多远。该字段的单位是32位(即4个字节为计算单位),4位二进制最大表示15,所以数据偏移也就是TCP首部最大60字节。

URG(紧急位) :表示本报文段中发送的数据是否包含紧急数据。后面的紧急指针字段(urgent pointer)只有当URG=1时才有效

ACK(确认位) : 表示是否前面确认号字段是否有效。只有当ACK=1时,前面的确认号字段才有效;当ACK=0时,确认序列号无效。TCP规定,连接建立后,ACK必须为1,带ACK标志的TCP报文段称为确认报文段。

PSH(急切位) : 提示接收端应用程序应该立即从TCP接收缓冲区中读走数据,为接收后续数据腾出空间。如果为1,则表示对方应当立即把数据提交给上层应用,而不是缓存起来,如果应用程序不将接收到的数据读走,就会一直停留在TCP接收缓冲区中。

RST(重置位) : 如果收到一个RST=1的报文,说明与主机的连接出现了严重错误(如主机崩溃),必须释放连接,然后再重新建立连接。或者说明上次发送给主机的数据有问题,主机拒绝响应,带RST标志的TCP报文段称为复位报文段。

SYN(同步位) : 在建立连接时使用,用来同步序号。当SYN=1,ACK=0时,表示这是一个请求建立连接的报文段;当SYN=1,ACK=1时,表示对方同意建立连接。SYN=1,说明这是一个请求建立连接或同意建立连接的报文。只有在前两次握手中SYN才置为1,带SYN标志的TCP报文段称为同步报文段。

FIN(断开位) : 表示通知对方本端要关闭连接了,标记数据是否发送完毕。如果FIN=1,即告诉对方:“我的数据已经发送完毕,你可以释放连接了”,带FIN标志的TCP报文段称为结束报文段

窗口大小: 表示现在允许对方发送的数据量,也就是告诉对方,从本报文段的确认号开始允许对方发送的数据量,达到此值,需要ACK确认后才能再继续传送后面数据,由Window size value * Window size scaling factor(此值在三次握手阶段TCP选项Window scale协商得到)得出此值

校验和: 提供额外的可靠性紧急指针:标记紧急数据在数据字段中的位置

选项部分: 其最大长度可根据TCP首部长度进行推算。TCP首部长度用4位表示,选项部分最长为:(2^4-1)*4-20=40字节

4.UDP协议

UDP是一种无连接的协议,提供不可靠但效率较高的数据传输。它不需要建立连接,只是简单地将数据报发送到目标主机,但不保证数据的可靠性和顺序性。UDP适用于对实时性要求较高的应用,如音频和视频流媒体。

  • 工作在传输层
  • 提供不可靠的网络访问
  • 非面向连接协议
  • 有限的错误检查
  • 传输性能高
  • 无数据恢复特性

image.png

Source Port:16位数据源端口,在需要对方回信时选用,不需要时可用全0

Destination Port: 16位数据接收方端口号,在终点交付报文时必须用到。

Length:数据报和首部的长度,最小值为8Byte(数据报为空)

Check Sum:整个数据报文的检验和(IPv4 可选 字段),检测UDP数据报在传输中是否有错,有错就丢弃。该字段时可选的,当源主机不想计算校验和,则直接令该字段为全0。当传输层IP层收到UDP数据报时,就根据首部中的目的端口,把UDP数据报通过相应的端口,上交给进程。如果接收方UDP发现收到的报文中目的端口号不正确(即不存在对应端口号的应用进程),就丢弃该报文,并由ICMP发送“端口不可达”差错报文交给发送方。

二、TCP三次握手原理

TCP三次握手原理:客户端向服务器发送SYN同步请求,请求与服务器建立连接,服务器收到此SYN同步请求后,会针对客户端的SYN同步请求进行ACK响应的同时也会发送一个SYN同步请求,当客户端收到服务器发过来的SYN同步请求时,会给予一个ACK响应。

控制位

- 同步位 SYN=1 请求建立连接 
- 确认位 ACK=1 同意连接 
- 断开位 FIN=1 断开连接 
- 序列号 Seq 
- 确认号 ack

1.建立连接三次握手

6101fa351dc044c5def9448f750a5e1.png

  • 第一次握手:客户端向服务器发送SYN=1报文,并进入 SYN_SENT(同步已发送) 状态,等待服务器的确认;

  • 第二次握手:服务器收到SYN=1报文,向客户端发送SYN=1和 ACK=1的确认报文,此时服务器进入 SYN_RCVD(同步收到)状态;

  • 第三次握手:客户端收到 SYN=1ACK=1的报文段,向服务器发送ACK=1确认包,客户端进入ESTABLISHED(已建立连接)状态。服务器收到客户端的ACK=1包后也进入ESTABLISHED(已建立连接) 状态,完成三次握手。

2.断开连接四次挥手

367bf2dc0d7dbc80111cf788ef197ac.png

  • 第一次挥手:客户端向服务器发送 FIN=1 和ACK=1的报文段 ,之后进入FIN_WAIT_1状态。

  • 第二次挥手:服务器接收到客户端请求断开连接的报文后,向客户端返回ACK=1的报文段。检查是否有未传输完的数据,若有则继续传输。此时服务端进入CLOSE_WAIT状态,客户端进入FIN_WAIT_2状态。

  • 第三次挥手:数据全部传输完后,服务器向客户端发送FIN=1 和ACK=1的报文段 。进入LAST_ACK状态 。

  • 第四次挥手:客户端收到服务器的 FIN 包后,返回ACK=1的报文段,此时客户端就进入了 TIME_WAIT 状态。注意此时 TCP 连接还没有释放,必须经过 2*MSL 后,才进入 CLOSED 状态。而服务器收到客户端的 ACK 确认包后就进入了 CLOSED 状态,可以看出服务器端结束 TCP 连接的时间要比客户端早一些。

3.重要知识

知识:第三次握手可以包含数据,通过快速打开(TFO)技术可以实现

问题1:为什么TCP建立连接需要三次握手,明明两次就可以建立起连接?

答:因为为了防止出现失效的连接请求报文段被服务端接收的情况,从而发生错误。 可以想象一下,如果发送端发送了一个连接请求A,但是因为网络原因造成了超时,这时TCP会启动超时重传机制再次发送一个连接请求B,此时请求顺利到达接收端,接收端应答完就建立了请求,然后发送完数据后断开连接。最后请求A在两端关闭完了到达了接收端,那么此时的接收端会认为又要建立连接,从而应答了请求并进入ESTABLISHED状态。但是客户端其实是CLOSED状态,那么就会导致服务端一直等待,造成资源浪费。

知识:在建立连接中,任意一段掉线,TCP都会重新发SYN包,一般会重试五次,在建立中可能会遇到SYN Flood。遇到这种情况可以选择调低重试次数或干脆在不能处理的情况拒绝请求。

问题2:为什么不是四次?

答:三次握手的目的是确认双方发送和接收的能力,100 次都可以。但为了解决问题,三次就足够了,再多用处就不大了。

问题3:为什么接收端要进入TIME-WAIT等待2MSL时间CLOSE

答:保证接收端发送的最后一个ACK报文能够到达服务器,因为这个ACK报文可能丢失或超时,发送端没有收到回应,于是服务器会重新发送一次,而接收端就能在2MSL时间内接收到重传的报文,接着给出回应报文,并且会重启2MSL计时器,防止‘已失效的连接请求出现在本报文中’。若接收端发完确认应答后直接进入 CLOSED 状态,如果确认应答因为网络问题一直没有到达,那么会造成发送端不能正常关闭。

问题四:为什么建立连接是三次握手,关闭连接确是四次挥手呢?

答:建立连接的时候, 服务器在LISTEN状态下,收到建立连接请求的SYN报文后,把ACKSYN放在一个报文里发送给客户端。而关闭连接时,服务器收到对方的FIN报文时,仅仅表示对方不再发送数据了但是还能接收数据,而自己也未必全部数据都发送给对方了,所以己方可以立即关闭,也可以发送一些数据给对方后,再发送FIN报文给对方来表示同意现在关闭连接,因此,己方ACKFIN一般都会分开发送,从而导致多了一次。