TCP 总结
TCP/IP 协议族
一系列协议所组成的一个网络分层模型。
为什么要分层
因为网络的不稳定性。上层的开发可以直接依赖下层的功能而无需理会具体的实现,简便了开发。
具体分层
应用层(Application Layer): HTTP、FTP、DNS
传输层(Transport Layer): TCP、UDP
网络层(Intenet Layer): IP
数据链路层(Link Layer): 以太网、WIFI
TCP 的特性
TCP 提供一种面向连接的、可靠的字节流服务。
TCP 的三次握手和四次挥手
客户端简称 A ,服务端简称 B
三次握手
TCP 建立连接需要三次握手
- A 向 B 表示想跟 B 进行连接(A 发送 syn 包,A 进入 SYN_SENT 状态);
- B 收到消息,表示我也准备好和你连接了(B 收到 syn 包,需要确认 syn 包,并且自己也发送了一个 syn 包,即发送了 syn + ack,B 进入了 SYN_RECV 状态);
- A 收到消息,并告诉 B 表示我收到你准备连接的信号了(A 收到 syn + ack ,向 B 发送 ack 包,A B进入 established 状态)开始连接。
两次握手可以吗?
不可以。
两次握手会产生一个问题,B 没有办法知道 A 是否已经接收了自己的同步信号,一旦这个同步信号丢了,A 和 B 就 B 的初始序列号就无法达成一致。
比如:A 发送第一个 syn 包,但是在网络中阻塞了,于是 A 发了第二个 syn 包,如果是两次握手,当A的两个 syn 包都到达 B,就会建立了一个并不需要的连接,浪费了资源还可能导致不必要的错误。
四次挥手
TCP断开连接需要四次挥手
- A 向 B 表示想跟 B 断开连接(A 发送 fin 包,A 进入 FIN_WAIT_1 状态);
- B 收到消息,但是 B 消息没发送完,只能告诉 A 我收到你的断开连接的消息(B 收到 fin 包,发送 ack 包,进入 CLOSE_WAIT 状态,A收到 ack 包会进入 FIN_WAIT_2 状态);
- 过一会,B 数据发送完毕,告诉 A ,我可以和你断开了(B 发送 fin包,B 进入 LAST_ACK 状态);
- A 收到消息,告诉 B,可以和它断开(A 收到 fin 包,向 B 发送 ack 包,A进入 TIME_WAIT 状态,B 收到 ack 包后进入 closed 状态,A 等待 两个报文存活的最大时长后进入closed 状态)
当 A 收到 B 的 fin 包时,理想状态下,是可以关闭连接的,但是
- 由于网络的不稳定性,可能 B 发送的一些数据还没到达(比 fin 包慢)
- A 回复的 ack 包可能丢失了,B会重传 fin 包
如果 A 马上关闭连接,会导致数据不完整,B 无法释放连接等问题,所以 A 需要等待两个报文生存的最大时长。
为什么需要四次挥手
因为挥手第二步的时候不能保证 B 的数据已经发送完毕,所以不能马上告诉 A 要断开的消息。
SYN 攻击
什么是 SYN 攻击
在三次握手的过程中,服务器在发送 syn-ack 包之后,收到客户端的 ack 包之前的 TCP 连接成为半连接(half open connect),此时服务器处于 SYN_RECV 状态。
SYN 攻击是指,攻击客户端在短时间伪造大量不存在的 IP 地址,向服务不断发送 syn 包,服务器回复确认包,服务器需要不断的重发直至超时,这些伪造的 SYN 包将长时间占用未连接队列,正常的 SYN 请求被丢弃,导致目标系统运行缓慢,严重者会引起网络堵塞甚至系统瘫痪。
SYN 攻击是一种典型的 DoS/DDoS 攻击。
防御 SYN 攻击
SYN攻击不能完全被阻止,所做的是尽可能的减轻SYN攻击的危害,常见的防御 SYN 攻击的方法有如下几种:
- 缩短超时(SYN Timeout)时间
- 增加最大半连接数
- 过滤网关防护
- SYN cookies 技术
长连接
为什么要长连接
移动网络并不在 Internet 中,而是在运营商的内网,并不具有真正的公网 IP,当某个 TCP 连接在一段时间不通信后,网关会处于网络性能考虑而关闭这条 TCP 连接和公网的连接通道,导致这个 TCP 端口不能在收到外部通道的消息,即 TCP 连接被动关闭。
实现方式
心跳。在一定间隔时间内,使用 TCP 连接发送超短无意义数据,来让网关不能将自己定义为空闲连接,从而防止网关将自己的连接关闭。