阅读 315

TCP三次握手与四次挥手

前置知识

TCP标志位

  • SYN: 同步标志位,用于建立会话连接,同步序列号
  • ACK: 确认标志位,对已接收的数据包进行确认
  • FIN: 完成标志位,表示我已经没有数据要发送了,即将关闭连接
  • PSH: 推送标志位,表示该数据包被对方接收后应立即交给上层应用,而不在缓冲区排队
  • RST: 重置标志位,用于连接复位、拒绝错误和非法的数据包
  • URG: 紧急标志位,表示数据包的紧急指针域有效,用来保证连接不被阻断,并督促中间设备尽快处理

TCP三次握手

所谓三次握手(Three-way Handshake),是指建立一个 TCP 连接时,需要客户端和服务器总共发送3个报文

  • 客户端首先发送将 TCP报文标志位SYN置为1,随机产生一个序号值seq的数据包给服务端

    SYN = 1,seq = client_isn

  • 服务端收到后,回传一个SYN/ACK标志为1的数据包给客户端

    SYN = 1, ACK = 1, ack = client_isn + 1, seq = server_isn

  • 最后,客户端再回传一个带ACK标志的数据包,代表握手结束

    ACK = 1, ack = server_isn + 1, seq = client_isn + 1

Acknowledge number缩写ack,表示告知已收到的值,Sequence number缩写seq,序列值

相关问题

为什么要三次握手?

三次握手最主要的目的就是双方确认自己与对方的发送与接收是正常的。防止已经失效的连接请求报文突然又传到服务器。比如第一个请求 发送后没有丢失但是在网络节点中存在太长。而客户端在长时间没有收到确认报文,就会认为服务器没有收到,又会重新去新的连接报文。 假设没有第三次握手。那么这个延迟的报文在达到服务器后,服务器确认,此时就会让服务器和客户端进行不必要连接,而采取三次,服务器 确认后,但是收不到客户端的最后一次确认,那么这次连接就不会建立

为什么三次握手,返回时,ack 值是 seq 加 1(ack = x+1)
  • 确认收到的序列,并且告诉发送端下一次发送的序列号从哪里开始
  • 表示编号seq+1前的字节接受完成
SYN洪泛攻击(SYN Flood,半开放攻击),怎么解决?
  • 什么是SYN洪范泛攻击?

    SYN Flood利用TCP协议缺陷,发送大量伪造的TCP连接请求,常用假冒的IP或IP号段发来海量的请求连接的第一个握手包(SYN包),被攻击服务器回应第二个握手包(SYN+ACK包),因为对方是假冒IP,对方永远收不到包且不会回应第三个握手包。导致被攻击服务器保持大量SYN_RECV状态的“半连接”,并且会重试默认5次回应第二个握手包,大量随机的恶意syn占满了未完成连接队列,导致正常合法的syn排不上队列,让正常的业务请求连接不进来。
    服务器端的资源分配是在二次握手时分配的,而客户端的资源是在完成三次握手时分配的,所以服务器容易受到SYN洪泛攻击

  • 如何判断是SYN洪范泛攻击

    服务器上看到大量的半连接状态时,特别是源IP地址是随机的,基本上可以断定这是一次SYN攻击

  • 怎么解决?

    缩短超时(SYN Timeout)时间, 增加最大半连接数, SYN cookies技术

TCP三次握手中,最后一次回复丢失,会发生什么?
  • 根据 TCP的超时重传机制依次等待3秒、6秒、12秒后重新发送 SYN+ACK 包,以便 Client(客户端)重新发送ACK包
  • 如果重发指定次数后,仍然未收到ACK应答,那么一段时间后,Server(服务端)自动关闭这个连接
  • 但是客户端认为这个连接已经建立,如果客户端向服务端发送数据,服务端将以RST包(Reset,标示复位,用于异常的关闭连接)响应,此时,客户端知道第三次握手失败
ISN代表什么?意义何在?ISN是固定不变的吗?
  • ISN,发送方的字节数据编号的原点,让对方生成一个合法的接收窗口。
  • ISN为了增加安全性,是动态随机的
三次握手的第一次可以携带数据吗?为何?
  • 不可以,三次握手还没有完成。会导致SYN洪泛攻击更加凶猛
第三次可以携带数据吗?为何?
  • 可以,能够发出第三次握手报文的,应该是合法的用户。伪造IP的主机是不会接收到第二次报文的。而且尽管服务器侧的状态还没有变更,接收到第三次握手的瞬间,立即就会切换到连接成功,里面携带的数据按照正常流程走就好

TCP四次挥手

四次挥手即终止TCP连接,就是指断开一个TCP连接时,需要客户端和服务端总共发送4个包以确认连接的断开,挥手请求可以是Client端,也可以是Server端发起的

  • A(客户端/服务端)-发送一个 FIN,用来关闭 A(客户端/服务端)到 B(客户端/服务端)的数据传送

    FIN = 1,seq = u

  • B-收到这个 FIN,它发回一 个 ACK,确认序号为收到的序号加1

    ACK = 1, ack = u + 1, seq = v

  • B-关闭与主动断开方A的连接,发送一个FIN给A

    FIN = 1, ACK = 1, ack = u + 1, seq = w

  • A-发回 ACK 报文确认,并将确认序号设置为收到序号加1

    ACK = 1, ack = w + 1, seq = u + 1

  • 状态总结:
    • A发出连接释放报文段并处于FIN-WAIT-1状态
    • B发出确认报文段且进入CLOSE-WAIT状态
    • A收到确认后,进入FIN-WAIT-2状态,等待B的连接释放报文段——B没有要向A发出的数据
    • B发出连接释放报文段且进入LAST-ACK状态
    • A发出确认报文段且进入TIME-WAIT状态——B收到确认报文段后进入CLOSED状态——A经过等待计时器时间2MSL后,进入CLOSED状态。

相关问题

为什么连接的时候是三次握手,关闭的时候却是四次握手?

关闭连接时,服务器收到对方的FIN报文时,仅仅表示对方不再发送数据了但是还能接收数据,而自己也未必全部数据都发送给对方了, 所以服务器可以立即关闭,也可以发送一些数据给对方后,再发送FIN报文给对方来表示同意现在关闭连接。 因此,服务器ACK和FIN一般都会分开发送,从而导致多了一次。

为什么TCP挥手每两次中间有一个 FIN-WAIT2等待时间?

定时器,防止因意外,未收到对端发送的(FIN,ACK)包时,直接进入close状态

什么主动关闭端最后还要等待2MSL?为什么还有个TIME-WAIT的时间等待?
  • 2MSL,最大报文生存时间,一个MSL 30 秒,2MSL = 60s
  • 保证TCP协议的全双工连接能够可靠关闭
  • 保证这次连接的重复数据段从网络中消失
文章分类
前端
文章标签