三次握手:
- 客户端向服务器端发送带有SYN标志的数据包,发送完毕之后,进入syn-send(同步已发送)状态,等待服务器端的确认。
- 服务器端收到SYN包后,如果同意建立连接,则向客户端发送SYN+ACK确认包,发送完毕之后,服务器端进入syn-recv(同步收到)状态。
- 客户端收到服务器端的确认后,向服务器端发送ACK确认包,此包发送完毕之后,客户端和服务器端进入established(已建立连接)状态。
四次挥手:
1.客户端向服务器端发送带有FIN标志的数据包,请求断开连接,发送完毕之后,客户端进入fin-wait-1(终止等待1)状态。
2.服务器端收到FIN包后,发送一个ACK给客户端,发送完毕之后,服务器端进入close-wait(关闭等待)状态。
3.客户端收到服务器端的FIN+ACK包后,进入fin-wait-2(终止等待2)状态。服务器端发送一个FIN包,用来关闭客户端和服务器端的数据传送。即服务器端告诉客户端,我的数据已传送完毕,不会再给你发送数据。此时,服务器端进入last-ack(最后确认)状态。
4.客户端收到FIN包后,发送一个ACK给服务器端,此时,客户端进入time-wait(时间等待)状态。服务器端进入closed状态。
为什么是三次握手,两次握手可以吗?
假设A为客户端,B为服务器端。
采用三次握手是为了防止已失效的连接请求突然又传送到B,因而产生错误。
正常情况下:A发出连接请求,但因请求报文丢失而未收到确认。于是A再重传一次连接请求,收到确认后,建立连接,完成数据传输。数据传输完毕后,释放连接。
异常情况下:A发出连接请求,该请求报文并没有丢失,而是在某些网络节点长时间滞留了,以致连接释放后的某个时间才到达B。
B收到失效的连接请求后,误以为是A再次发送连接请求,于是向A发送确认报文,同意建立连接。
如果不采用3次握手,B发出确认报文后,新的连接就会建立。
但此刻A并没有发送连接请求,因此不会理睬B的确认,也不会向B发送数据,而B却一直等待A发来数据,导致B的很多资源浪费。
所以,需要进行3次握手。