简述TCP三次握手
三次握手过程
初始状态
客户端处于closed(关闭)状态,服务器处于listen(监听)状态
第一次握手
客户端向服务器发送SYN报文,并指明初始化序列号ISN(作为seq字段的值)
此时客户端处于SYN_Send状态
第二次握手
服务器收到后,会返回SYN+ACK报文,在这个报文中,服务器指定自己的初始化序列号ISN(作为seq字段的值),同时把客户端的ISN+1作为ACK字段的值;并为该连接分配缓存和变量
此时服务器处于SYN_receive状态
第三次握手
客户端收到服务器的应答后,会发送ACK报文,在这个报文中,把服务器的ISN+1作为ACK的值;并为该连接分配缓存和变量
此时客户端处于establised状态
服务器收到ACK报文后,也进入established状态,此时TCP连接建立完成
三次握手的作用
1、确认通信双方的接收、发送能力是否正常
第一次握手后,服务器知道了:客户端的发送能力正常
第二次握手后,客户端知道了:服务器的接收和发送能力正常
第三次握手后,服务器知道了:客户端的接收能力也是正常的
2、防止服务器一直等待而浪费资源
如果客户端发送的SYN报文在某个网络节点滞留,服务器收到后,认为客户端要和它建立连接
如果是2次握手,那么当服务器对这个延迟的、失效的握手请求进行响应后,就会进入established状态,并一直等待客户端发送数据,然而客户端没有这个意思,这样就会造成服务器资源的浪费
3、指定自己的初始化序列号,为后面的可靠传输做准备
4、如果是https协议,三次握手这个过程,还涉及到数字证书的验证以及密钥的生成
一些补充
ISN
ISN是发送方的字节数据编号的初始值,接收方可以根据ISN生成一个合法的接收窗口
ISN是动态生成的,这样做是为了增加安全性,避免攻击者猜出后续的确认号
半连接队列
在第二次握手后,服务器处于SYN_Receive状态,并正在等待客户端的ACK报文
服务器会把这种状态下的请求连接放在一个队列中,这个队列就称为半连接队列
(已经完成三次握手的,就会放在全连接队列中)
握手过程中可以携带数据吗
第一次握手是不可以携带数据的,因为这样会让服务器更容易受到SYN FLOOD攻击
假如第一次握手可以携带数据的话,如果有人要恶意攻击服务器,那么他会在第一次握手的SYN报文中放入大量数据,并在短时间内大量发送SYN报文,让服务器花费很多时间和内存来接收这些报文,耗尽服务器的半连接队列,使得正常的连接请求无法得到处理
第三次握手是可以携带数据的
因为在第三次握手时,客户端已经处于established状态,并且已经确认服务器的发送、接收能力都是正常的