为什么不二次握手?

提出问题:
对于tcp建立连接,客户端向服务器发送建立tcp连接的请求(包含参数“接收窗口大小”、“最大传输报文段大小”、“是否接收选择性确认”等),服务器接收到请求后,响应此请求将服务器的“接收窗口大小”、“最大传输报文段大小”、“是否接收选择性确认”等信息返回给客户端即可建立连接,为什么会需要三次握手?

问题分析:
三次握手及释放 - 图1
若采用两次握手,会存在一种情况:

  1. A向B发起建立TCP连接请求,此次请求可以选择的路径比较远,A还未收到;
  2. A等待了一段时间未接收到第一次请求的响应,认为第一次请求失效,则会再发第二次建立连接请求。
  3. 第二次连接请求先到达B,给A回复了响应;
  4. 过一段时间第一次连接请求到达B,给A回复响应;

存在问题: 此时A认为与B建立了两次连接,A会为B预留资源等待两次连接后续的请求,但是B认为第一次请求已经作废,不会再发送后续请求,导致A的资源有浪费。

解决方法:
通过三次握手建立连接, 在上面的基础上再增加B向A的反馈,对于上述问题,B收到第二次请求的响应,会再给A发送确认消息,收到第一次请求的响应,则不做回复. A未收到后面一次的确认,则不会再预留资源等待.

TCP建立连接-三次握手

实现过程

image.png
说明:
1)A、B最初tcp连接状态都是CLOSED,服务启动后,B状态变为LISTEN监听状态。
2)A发送消息(tcp首部:SYN=1,ACK=0,seq=x),A的状态变为SYN_SENT,等待B响应,若超出RTT往返时间,会再次发送一条建立tcp连接请求
3)B接收到连接请求后,B确认连接,返回消息(tcp首部:SYN=1,ACK=1,seq=y,ack=x+1),此时tcp连接状态变为SYN_RCVD。
4)A收到确认消息,则会再发一条确认的确认消息(tcp首部:ACK=1,seq=x+1,ack=y+1),A的连接状态变为ESTABLISHED
5)B接收到确认的确认消息,状态也变为ESTABLISHED。
image.png
image.png
image.png

抓包实战

通过ping www.baidu.com , DNS返回百度的地址为180.101.49.12
image.png
开启wireshake抓包, 浏览器访问www.baidu.com
image.png

SYN攻击

SYN攻击属于DoS攻击的一种,它利用TCP协议通信建立连接,使用伪造的源IP地址给服务器发送大量的TCP连接请求报文,服务器会给这些伪造的源地址发送连接确认报文,这时服务器就会进入SYN-RCVD状态,等待客户端确认报文。
image.png

TCP释放连接-四次握手

实现过程

image.png
说明:
1)客户但与服务器建立连接后,tcp连接状态都是ESTABLISHED
2)客户端不再往服务器发送数据后,发出一条请求(tcp首部:FIN=1,seq=u),此时客户端连接状态变为FIN_WAIT_1。
3)服务器接收到释放连接的请求后,通知应用进程进行处理并发送一条确认请求(tcp首部:ACK=1,seq=v,ack=u+1),服务器的状态变为CLOSE_WAIT,此时服务器还可以往客户端发送数据。
4)客户端接收到服务器的确认消息,tcp状态变为FIN_WAIT_2,此时客户端不能再向服务器发送数据。
5)服务器应用进程不再往客户端发送数据后,发出一条释放连接的请求(tcp首部:FIN=1,ACK=1,seq=w,ack=u+1),tcp状态变为LAST_ACK。
6)客户端接收到服务器的释放连接请求,会发出一条确认消息(tcp首部:ACK=1,seq=u+1,ack=w+1),等待一段时间(即TCP状态为TIME_WAIT),等待一段时间的原因:防止客户端发出的确认消息在中途丢失,服务器未接收到确认消息,会再发送一次释放连接请求,等待一段时间后tcp状态变为CLOSED。
7)服务器接收到客户端的确认消息后,tcp连接状态变为CLOSED
image.png

TCP的有限状态机

image.png

TCP连接状态查看

image.png