1. TCP
1. TCP
1.1 概念
- 面向连接、可靠的基于字节流的传输协议。
- 将应用层的的数据分割成报文段并发送给目标节点的 TCP 层
- 每个数据包都有相对应的序号,对方收到后就发送 ACK 确认,未收到就重传
- 使用校验和来检测传输过程中是否出现错误
1.2 TCP 报文头
TCP 报文头1.3 TCP 报文头字段含义
1. Source Port和Destination Port:
分别占用16位,表示源端口号和目的端口号,用于区别主机中的不同进程, 而IP地址是用来区分不同的主机的,源端口号和目的端口号配合上IP首部中的源IP地址和目的IP地址就能唯一 的确定一个TCP连接。
2. Sequence Number:
用来标识从TCP发端向TCP收端发送的数据字节流,它表示在这个报文段中的的第一个数据 字节在数据流中的序号;主要用来解决网络报文乱序的问题。
3. Acknowledgment Number:
32位确认序列号包含发送确认的一端所期望收到的下一个序号,因此,确认序号应 当是上次已成功收到数据字节序号加1。不过,只有当标志位中的ACK标志(下面介绍)为1时该确认序列号的字 段才有效。主要用来解决不丢包的问题。
4. Offset:
给出首部中32 bit字的数目,需要这个值是因为任选字段的长度是可变的。这个字段占4bit(最多能 表示15个32bit的的字,即4*15=60个字节的首部长度),因此TCP最多有60字节的首部。然而,没有任选字段, 正常的长度是20字节。
5. TCP Flags:
TCP首部中有6个标志比特,它们中的多个可同时被设置为1,主要是用于操控TCP的状态机的,依次 为URG,ACK,PSH,RST,SYN,FIN。每个标志位的意思如下:
-
URG:此标志表示TCP包的紧急指针域(后面马上就要说到)有效,用来保证TCP连接不被中断,并且督促 中间层设备要尽快处理这些数据。
-
ACK 此标志表示应答域有效,就是说前面所说的TCP应答号将会包含在TCP数据包中;有两个取值:0和1, 为1的时候表示应答域有效,反之为0。
-
PSH:这个标志位表示Push操作。所谓Push操作就是指在数据包到达接收端以后,立即传送给应用程序, 而不是在缓冲区中排队。
-
RST:这个标志表示连接复位请求。用来复位那些产生错误的连接,也被用来拒绝错误和非法的数据包。
-
SYN:表示同步序号,用来建立连接。SYN标志位和ACK标志位搭配使用,当连接请求的时候,SYN=1, ACK=0;连接被响应的时候,SYN=1,ACK=1;这个标志的数据包经常被用来进行端口扫描。扫描者发送 一个只有SYN的数据包,如果对方主机响应了一个数据包回来 ,就表明这台主机存在这个端口;但是由于这 种扫描方式只是进行TCP三次握手的第一次握手,因此这种扫描的成功表示被扫描的机器不很安全,一台安全 的主机将会强制要求一个连接严格的进行TCP的三次握手。
-
FIN:表示发送端已经达到数据末尾,也就是说双方的数据传送完成,没有数据可以传送了,发送FIN标志 位的TCP数据包后,连接将被断开。这个标志的数据包也经常被用于进行端口扫描。
6. Window:
滑动窗口大小 (流量控制)。
7. 校验和:
奇偶校验,此校验和是对整个的 TCP 报文段,包括 TCP 头部和 TCP 数据,以 16 位字进行计算所得。由发送端计算和存储,并由接收端进行验证。
8. 紧急指针:
只有当 URG 标志置 1 时紧急指针才有效。紧急指针是一个正的偏移量,和顺序号字段中的值相加表示紧急数据最后一个字节的序号。 TCP 的紧急方式是发送端向另一端发送紧急数据的一种方式。
9. 选项和填充:
最常见的可选字段是最长报文大小,又称为MSS(Maximum Segment Size),每个连接方通常都在通信的第一个报文段(为建立连接而设置SYN标志为1的那个段)中指明这个选项,它表示本端所能接受的最大报文段的长度。选项长度不一定是32位的整数倍,所以要加填充位,即在这个字段中加入额外的零,以保证TCP头是32的整数倍。
10. 数据部分:
TCP 报文段中的数据部分是可选的。在一个连接建立和一个连接终止时,双方交换的报文段仅有 TCP 首部。如果一方没有数据要发送,也使用没有任何数据的首部来确认收到的数据。在处理超时的许多情况中,也会发送不带任何数据的报文段。
2. 三次握手
2.1 原因
为什么需要三次握手:
- IP 是位于网络层的无连接的通讯协议,IP 协议只负责将 IP 包送往发送给目的地,但不确保发送到目的地,所以在传输层采用有连接的方式,来确保数据的送
达。
2.2 概念
所谓三次握手是指建立一个 TCP 连接时需要客户端和服务器端总共发送三个包以确认连接的建立。在socket编程中,这一过程由客户端执行connect来触发。
2.3 三次握手的流程图
三次握手的流程图2.4 流程图的解释
- 第一次握手:客户端将标志位SYN置为1,随机产生一个值seq=J,并将该数据包发送给服务器端,客户端进入SYN_SENT状态,等待服务器端确认。
- 第二次握手:服务器端收到数据包后由标志位SYN=1知道客户端请求建立连接,服务器端将标志位SYN和ACK都置为1,ack=J+1,随机产生一个值seq=K,并将该数据包发送给客户端以确认连接请求,服务器端进入SYN_RCVD状态。
- 第三次握手:客户端收到确认后,检查ack是否为J+1,ACK是否为1,如果正确则将标志位ACK置为1,ack=K+1,并将该数据包发送给服务器端,服务器端检查ack是否为K+1,ACK是否为1,如果正确则连接建立成功,客户端和服务器端进入ESTABLISHED状态,完成三次握手,随后客户端与服务器端之间可以开始传输数据了。
2.5 安全隐患
2.5.1 首次握手 —— SYN 超时
在 Server 收到 Client 的 SYN 之后,回复 SYN-ACK 的时候未收到 ACK 确认,导致服务端不断重试,直到超时。
2.5.2 SYN Flood 攻击
恶意程序会在短时间对服务器不断发起建立连接请求,但不响应服务器请求,导致服务器不断重发,占用资源,导致崩溃。
2.5.3 应对 SYN Flood 攻击的方式
- SYN 队列满后,通过 tcp_syncookies 参数回发 SYN Cookie
- 若为正常连接,则 Client 会回发 SYN Cookie,建立连接
2.6 建立连接后,Client 故障
2.6.1 保活机制
向 Client 发送探测报文,如果未收到响应则继续发送,直到收到响应或达到保活探测数时,中断连接。
3. 四次挥手
3.1 原因
由于TCP连接是全双工的,因此,每个方向都必须要单独进行关闭,这一原则是当一方完成数据发送任务后,发送一个FIN来终止这一方向的连接,收到一个FIN只是意味着这一方向上没有数据流动了,即不会再收到数据了,但是在这个TCP连接上仍然能够发送数据,直到这一方向也发送了FIN。
3.2 概念
四次挥手即终止TCP连接,就是指断开一个TCP连接时,需要客户端和服务端总共发送4个包以确认连接的断开。在socket编程中,这一过程由客户端或服务端任一方执行close来触发。
3.3 四次挥手流程图
四次挥手流程图3.4 为什么客户端发送完最后一个 ACK 包之后还需要 TIME-WAIT
- 确保有足够的时间让对方接收到 ACK 包
- 避免新旧连接混淆
3.5 服务器出现大量 CLOSE-WAIT 状态的原因
客户端关闭 socket 连接,服务端忙于处理读或写,没有及时关闭连接
- 检查代码,特别是资源释放代码
- 检查配置,特别是处理请求的线程配置
4. TCP 滑动窗口
4.0 必知必会
RTT
发送数据包到收到对应的 ACK,中间所花费的时间
RTO
重传时间间隔(经过 RTT 计算得到)
4.1 滑动窗口的作用
TCP 使用滑动窗口做流量控制和乱序重排