三次握手 四次挥手
1.什么是三次握手,四次挥手
TCP是一种面向连接的单播协议,在发送数据前,通信双方必须在彼此间建立一条连接。在连接的建立过程中,双方需要交换一些连接的参数。这些参数可以放在TCP头部。TCP提供了一种可靠、面向连接、字节流、传输层的服务,采用3次握手建立一个连接。采用4次挥手来关闭一个连接。
TCP服务模型:
一个TCP连接由一个4元组构成,分别是两个IP地址和两个端口号。一个TCP连接通常分为三个阶段:启动、数据传输、退出(关闭)。
当TCP接收到另一端的数据时,它会发送一个确认,但这个确认不会立即发送,一般会延迟一会儿。ACK是累积的,一个确认字节号N的ACK表示所有直到N的字节(不包括N)已经成功被接收了。这样的好处是如果一个ACK丢失,很可能后续的ACK就足以确认前面的报文段了。
一个完整的TCP连接是双向和对称的,数据可以在两个方向上平等地流动。给上层应用程序提供一种双工服务。一旦建立了一个连接,这个连接的一个方向上的每个TCP报文段都包含了相反方向上的报文段的一个ACK。
序列号的作用是使得一个TCP接收端可丢弃重复的报文段,记录以杂乱次序到达的报文段。
序列号seq:占4个字节,用来标记数据段的顺序,TCP把连接中发送的所有数据字节都编上一个序号,第一个字节的编号由本地随机产生;给字节编上序号后,就给每一个报文段指派一个序号;序列号seq就是这个报文段中的第一个字节的数据编号。
todo:搞懂序列号seq,ack,syn等
2.三次握手
刚开始客户端处于closed的状态,服务端处于listen状态:
1.第一次握手:客户端发送给服务端一个SNS报文,并指明客户端的初始序列号ISN(c)。此时客户端处于SYN_SEND状态
2.第二次握手:服务器收到客户端的SYN报文后,会以自己的SYN报文作为应答,并且也是指定了自己的序列号ISN(s),同时把客户端的ISN+1作为ACK的值,表示自己已经收到了客户端SYN,此时服务器处于SYN_REVD的状态。
3.第三次握手:客户端接收到SYN报文后,会发送一个ACK报文,把服务器的ISN+1作为ACK的值,表示已经收到服务端SYN报文,此时客户端处于establish状态。
4.服务器收到ACK报文后,也处于establish状态,此时,双方监理了链接。
3.四次挥手
刚开始双方都处于establish状态,假设客户端发起关闭请求:
1.第一次挥手:客户端发送一个FIN报文,报文中会制定一个序列号K,同时还包含一个ACK表示确认对方最近一次发过来的数据。此时客户端处于FIN_WAIT1状态
2.第二次挥手:服务端收到FIN之后,会发送一个ACK报文,且把客户端发送过来的的序列号(K)+1作为ACK报文的序列号,表明服务端已经收到客户端报文,此时服务端处于CLOSE_WAIT状态。
3.第三次挥手:如果服务端也想断开连接了,和客户端一样,发送FIN报文,且制定一个序列号。此时服务端处于LAST_ACK状态。
4.第四次挥手:客户端收到FIN后,一样的发送ACK报文作为应答,且把服务端的序列号值+1作为自己ACK报文的序列号值,此时客户端处于TIME_WAIT状态。需要过一整子以确保服务端收到自己的ACK报文后才会进入CLOSED状态。
5.服务端收到ACK报文之后,就处于关闭连接了,处于CLOSSED状态。
4.为什么要三次握手
第一次握手:客户端发送网络包,服务端收到。这样服务端得出结论:客户端的发送能力正常,服务端接收能力正常。
第二次握手:服务端发包,客户端收到。这样客户端得出结论:服务端的接受能力正常,客户端发送能力正常。
从客户端角度看,我收到了服务端发送过来的响应,说明服务端收到了我第一次握手的网络包,并成功发送了响应数据包,这就说明,服务端的接受和发送能力正常。另一方面,我收到了服务端的响应数据包,说明我第一次发送的网络包成功到达了服务端,这样,我自己的发送和接收能力也是正常的。
第三次握手:客户端发包,服务端收到了。这样服务端就能得出结论:客户端的接收,发送能力时正常的。服务端的接送能力,接收能力也是正常的。第一,二次握手后,服务端并不知道客户端的接收能力以及自己的发送能力正常。而在第三次握手时,服务端收到了客户端第二次握手的响应。从服务端角度,我在第二次握手的响应数据发送出去了,客户端收到了。所以,我发送能力正常,而客户端接受能力正常。
5.为什么握手是三次,挥手却是四次
这是因为服务端在LISTEN状态下,收到建立连接请求的SYN报文后,把ACK和SYN放在一个报文里发送给客户端。而关闭连接时,当收到对方的FIN报文时,仅仅表示对方不再发送数据了但是还能接收数据,己方是否现在关闭发送数据通道,需要上层应用(对方)来决定,因此,己方ACK和FIN一般都会分开发送。