【网络编程】TCP的三次握手与四次挥手
TCP Flags
- URG 紧急指针标志
- ACK 确认序号标志
- PSH push标志
- RST 重置连接标志
- SYN 同步序号,用于建立连接过程
- FIN finish标志,用于释放连接
三次握手
1.为什么TCP客户端最后还要发送一次确认呢?
主要防止已经失效的连接请求报文突然又传送到了服务器,从而产生错误。
如果使用的是两次握手建立连接,假设有这样一种场景,客户端发送了第一个请求连接并且没有丢失,只是因为在网络结点中滞留的时间太长了,由于TCP的客户端迟迟没有收到确认报文,以为服务器没有收到,此时重新向服务器发送这条报文,此后客户端和服务器经过两次握手完成连接,传输数据,然后关闭连接。此时此前滞留的那一次请求连接,网络通畅了到达了服务器,这个报文本该是失效的,但是,两次握手的机制将会让客户端和服务器再次建立连接,这将导致不必要的错误和资源的浪费。
2.握手是为了建立连接
- 第一次握手:建立连接时,客户端发送SYN包(syn=j)到服务器,并进入SYN_SEND状态,等待服务确认。
- 第二次握手:服务器收到SYN包,必须确认客户端的SYN(ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态。
- 第三次握手:客户端收到服务端的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手。
3.为什么需要三次握手才能建立起连接
为了初始化seq的初始值
四次挥手
1.挥手 是为了终止连接
- 第一次挥手:client发送一个FIN,用来关闭client到server的数据传输,client进入FIN_WAIT_1状态。
- 第二次挥手:server收到FIN后,发送一个ACK给client,确认***为收到***+1(与SYN相同,一个FIN占用一个序号),server进入CLOSE_WAIT状态
- 第三次挥手:server发送一个FIN,用来关闭server到client的数据传送,server进入LAST_ACK状态;
- client收到FIN后,client进入TIME_WAIT状态,接着发一个ACK给server,确认序号为收到序号+1,server进入CLOSED状态,完成四次挥手。
2.为什么会有TIME_WAIT状态
- 确保有足够的时间让对方收到ACK包。
- 避免新旧连接混淆
3.为什么建立连接是三次握手,关闭连接确是四次挥手呢?
- 因为全双工,发送方和接收方都需要FIN报文和ACK报文
- 关闭连接时,服务器收到对方的FIN报文时,仅仅表示对方不再发送数据了但是还能接收数据,而自己也未必全部数据都发送给对方了,所以己方可以立即关闭,也可以发送一些数据给对方后,再发送FIN报文给对方来表示同意现在关闭连接,因此,己方ACK和FIN一般都会分开发送,从而导致多了一次。