TCP三次握手,四次挥手详解

TCP 三次握手

1.三次握手详解

三次握手(Three-Way Handshake)是指客户端与服务器一共发送三个包来建立TCP连接,三次握手的主要作用是为了确认双方的接受能力和发送能力是否正常,并同步序列号,保证传输的可靠性。

刚开始客户端和服务器均处于 CLOSED 状态,在socket编程中,服务器 listen() 之后被动打开,客户端 connection() 之后主动打开,之后进行三次握手:

分析方式(报文类型,编号,所处状态)

第一次握手:客户端给服务器发送SYN报文,并指明客户端的ISN,此时客户端处于SYN-SENT状态。
TCP报文头部 SYN = 1 , seq = x, SYN报文会消耗序列号,不能够携带数据。

第二次握手:服务器收到了客户端的SYN报文之后,会发送自己的SYN-ACK报文作为应答,在报文中指明了自己的ISN;并将客户端的 ISN + 1 作为ack值,发送给客户端,表示自己已经收到了客户端的SYN,此时服务器处于SYN-RCVD 状态。
TCP报文头部 SYN = 1, ACK = 1,seq = y, ack = x + 1,SYN报文会消耗序列号,不能携带数据。

第三次握手:客户端接收到服务器的SYN之后,发送ACK报文作为应答,将服务器的 ISN+1 作为 ack 的值,表示自己已经收到了服务器的SYN报文,发送后客户端进入 ESTABLISHED 状态,服务器收到ACK后也进入 ESTABLISHED 状态,双方开始数据交换。
TCP报文头部 ACK = 1, seq = x + 1,ack = y + 1, ACK报文如果携带数据则会消耗序列号,如果不携带数据则不会消耗序列号。

在这里插入图片描述

  1. 为什么要三次握手?只有两次握手可以吗?
    三次握手才能保证双方的接收发送能力都是正常的,第三次握手有两点作用:
    1.客户端的SYN报文因网络延时后滞后,此时客户端超时重传SYN报文并与服务器已经完成了数据的传输,随后第一次的SYN报文之后到达服务器,服务器误认为这是一次新的连接请求,于是发送SYN-ACK给客户端,但是客户端会直接忽略这一次SYN-ACK,导致服务器空等待。
    2.如果第二次握手的ACK信号丢失,服务器直接进入ESTABLISHED状态,而客户端没有收到,会形成服务器空等待。

  2. 什么是半连接队列?什么是全连接队列?
    在服务器收到客户端的SYN之后,进入SYN-RCVD状态,此时双方还没有完全建立连接,服务器将此状态称为半连接状态,并放入半连接队列中;全连接队列也就是存放完成了三次握手的连接的队列。

  3. ISN是什么?是固定的吗?
    ISN是一端为建立连接发送SYN时选择的一个初始序列号,ISN随时间而变化(每4ms加1),因此每一个连接都有不同的ISN。
    ISN不固定有两个好处:
    1.如果ISN固定,上一次连接的报文因网络延迟在这一次连接中到达,并恰好两次的seq相同,那么就会发生网络混乱。
    2.固定ISN容易遭受到黑客攻击,黑客能得知服务器的ISN,能在第三次握手正确的返回ACK报文,与服务器建立连接。

  4. 三次握手过程中可以携带数据吗?
    第一次第二次握手不行,第三次握手可以;
    假如第一次握手可以携带数据,那么如果有人要恶意攻击服务器,会在SYN报文中存入大量数据,并疯狂发送SYN报文,服务器将会因处理这些报文陷入瘫痪。
    第三次握手返回ACK报文时,双方连接已经建立,自然可以携带数据。

  5. SYN攻击是什么?SYN泛洪攻击是什么?
    Client伪造大量不存在的IP地址,并不断向Server发送SYN请求,由于IP地址不存在,Server会不断发送SYN-ACK报文直至超时,这些伪造的SYN报文将导致半连接队列满,导致正常的SYN请求因无法加入半连接队列而被丢弃,这样会造成服务器瘫痪。

常见的防御SYN攻击的方法有:
1.过滤网关防护
如设置SYN代理,让代理为服务器处理SYN请求,如果收到了客户端的ACK包那么就向服务器完成三次握手。
2.增大半连接队列容量
3.缩短超时时间与减少重传次数
4.SYNcookies技术

  1. 如果已经建立了连接,但是客户端突然出现故障了怎么办?
    服务端会有一个超时关闭机制,如果限定时间内没有接收到客户端的数据传送,那么就认为客户端已经出现故障, 服务器自动断开。

TCP 四次挥手

四次挥手详解

刚开始客户端和服务端都处于ESTABLISHED状态,假设客户端先发起关闭请求:
在Socket编程中,任意一方执行 close()操作,都会执行四次挥手。

第一次挥手:客户端向服务端发送FIN报文,同时指定自己的序列号,此时客户端处于 FIN-WAIT1 状态。
TCP报文头部信息:FIN = 1,seq = u,FIN会消耗一个序列号,不能携带数据。

第二次挥手:服务端接收到客户端的FIN报文后,发送ACK报文作为应答,ack值为客户端序列号+1,服务端处于 CLOSE-WAIT 状态,客户端收到ACK后处于FIN-WAIT2状态,此时TCP处于半关闭状态,服务端仍然在向客户端发送数据。
TCP报文头部信息:ACK = 1,seq = v,ack = u + 1,ACK报文携带数据则消耗序列号,不携带则不消耗序列号。

第三次挥手:服务端发送完数据之后,向客户端发送 FIN-ACK报文,同时指定自己的序列号,ack的值仍然为 客户端序列号 + 1,此时服务端处于 LAST-ACK 状态。
TCP报文头部信息:FIN = 1, ACK = 1,seq = w,ack = u + 1,FIN报文会消耗一个序列号,不能携带数据。

第四次挥手:客户端接收到服务端的FIN-ACK报文后,发送ACK报文给客户端,ack值为服务端序列号 + 1,此时客户端处于 TIME-WAIT 状态,需要等待 2MSL,之后进入CLOSED状态,服务端接收到ACK后也进入CLOSED状态。
TCP报文头部信息:ACK = 1,seq = u + 1, ack = w + 1,ACK报文携带数据会消耗序列号,不携带数据则不消耗序列号。

在这里插入图片描述

  1. 为什么连接的时候是三次握手,关闭的时候却是四次挥手?(为什么挥手需要四次?三次挥手不行吗?)
    三次握手的时候客户端发送SYN,服务器可以直接返回SYN-ACK;但是在四次挥手中,由于TCP的半关闭性,所以服务器收到FIN后,并不能立刻返回FIN-ACK,而是先发送ACK,等到数据传输完成之后,再发送FIN-ACK,这两个不能合到一起发送,所以需要四次挥手来关闭连接。

  2. 为什么客户端需要等待2MSL再关闭?
    原因有两点:
    1.保证客户端最后发送的ACK能够到达客户端
    如果这个ACK报文丢失,服务器超时重传FIN-ACK,客户端在2MSL的时间内一定可以接收到这个超时重传的FIN-ACK,这样可以避免服务器没有收到最后的ACK而空等待。
    2.防止旧连接中的报文影响新连接
    客户端在发送最后一个ACK后,等待2MSL,这样该连接中的所有报文都已经在网络中消失,不会影响到下一个新的连接。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值