代码随想录 | 八股-TCP连接
TCP连接三次握手的过程,为什么是三次,可以是两次或者更多吗?
- 三次握手的过程
第一次握手:客户端向服务器发送一个SYN (同步序列编号)报文,请求建立连接,客户端进入SYN_SENT 状态。 第二次握手:服务器收到SYN 报文后,如果同意建立连接,则会发送一个SYN-ACK (同步确认)报文作为响应,同时进入SYN_RCVD 状态。 第三次握手:客户端收到服务器的SYN-ACK 报文后,会发送一个ACK (确认)报文作为最终响应,之后客户端和服务器都进入ESTABLISHED 状态,连接建立成功。
(2)为什么需要三次握手 因为TCP需要简历双向的数据连接。通过三次握手,客户端和服务器都能够确认对方的接收和发送能力。第一次握手确认了客户端到服务器的通道是开放的;第二次握手确认了服务器到客户端的通道是开放的;第三次握手则确认了客户端接收到服务器的确认,从而确保了双方的通道都是可用的。
而如果仅使用两次握手,服务器可能无法确定客户端的接收能力是否正常,比如客户端可能已经关闭了连接,但之前发送的连接请求报文在网络上延迟到达了服务器,服务器就会主动去建立一个连接,但是客户端接收不到,导致资源的浪费。而四次握手可以优化为三次。
TCP连接四次挥手的过程,为什么是四次?
(1)四次挥手的过程
第一次挥手:客户端发送一个FIN报文给服务端,表示自己要断开数据传送,报文中会指定一个序列号 (seq=x)。然后,客户端进入FIN-WAIT-1 状态。 第二次挥手:服务端收到FIN报文后,回复ACK报文给客户端,且把客户端的序列号值+1,作为ACK报文的序列号(seq=x+1)。然后,服务端进入CLOSE-WAIT(seq=x+1)状态,客户端进入FIN-WAIT-2状态。 第三次挥手:服务端也要断开连接时,发送FIN报文给客户端,且指定一个序列号(seq=y+1),随后服务端进入LAST-ACK状态。 第四次挥手:客户端收到FIN报文后,发出ACK报文进行应答,并把服务端的序列号值+1作为ACK报文序列号(seq=y+2)。此时客户端进入TIME-WAIT状态。服务端在收到客户端的ACK 报文后进入CLOSE 状态。如果客户端等待2MSL没有收到回复,才关闭连接。
(2)为什么需要四次挥手
TCP是全双工通信,可以双向传输数据。任何一方都可以在数据传送结束后发出连接释放的通知,待对方确认后进入半关闭状态。 当另一方也没有数据再发送的时候,则发出连接释放通知,对方确认后才会完全关闭 TCP 连接。因此两次挥手可以释放一端到另一端的TCP连接,完全释放连接一共需要四次挥手。
只有通过四次挥手,才可以确保双方都能接收到对方的最后一个数据段的确认,主动关闭方在发送完最后一个ACK后进入TIME-WAIT 状态,这是为了确保被动关闭方接收到最终的ACK ,如果被动关闭方没有接收到,它可以重发FIN 报文,主动关闭方可以再次发送ACK 。
而如果使用三次挥手,被动关闭方可能在发送最后一个数据段后立即关闭连接,而主动关闭方可能还没有接收到这个数据段的确认。
HTTP的Keep-Alive是什么?TCP 的 Keepalive 和 HTTP 的 Keep-Alive 是一个东西吗?
HTTP 的 Keep-Alive,是由应用层实现的,称为 HTTP 长连接 每次请求都要经历这样的过程:建立 TCP连接 -> HTTP请求资源 -> 响应资源 -> 释放连接,这就是HTTP短连接,但是这样每次建立连接都只能请求一次资源,所以HTTP 的 Keep-Alive实现了使用同一个 TCP 连接来发送和接收多个 HTTP 请求/应答,避免了连接建立和释放的开销,就就是 HTTP 长连接。通过设置HTTP头Connection: keep-alive来实现。
TCP 的 Keepalive,是由TCP 层(内核态)实现的,称为 TCP 保活机制,是一种用于在 TCP 连接上检测空闲连接状态的机制 当TCP连接建立后,如果一段时间内没有任何数据传输,TCP Keepalive会发送探测包来检查连接是否仍然有效。
补充说明:
其实这里tcp的keepalive,不只是支持http,还可以支持ftp和smtp的,他是一个能力,类似于gc。
http的这个keepalive感觉更是一种策略吧,比如你有一个http用了keepalive,然后过了一会,你不传输数据了,这个时候没有通知对方close,这个时候tcp的keepalive就会起到用处去关闭这次链接。