三次握手
- 浏览器向服务器发送TCP数据:SYN(seq=x)
- 服务器向浏览器发送TCP数据:ACK(seq=x+1) SYN(y)
- 浏览器向服务器发送TCP数据:ACK(seq=y+1)
具体来说:
- 客户端发送一个SYN段,并指明客户端的初始序列号,即ISN(c)[x]
- 服务器发送自己的SYN段并作为应答,同样指明自己的ISN(s)[y]。为了确认客户端的SYN,将ISN(c)[x]+1作为自己的ACK数值。这样每发送一个SYN,序列号就加1,如果有丢失的情况,则会重传。
- 为了确认服务器端的SYN,客户端将ISN(s)[y]+1作为返回的ACK数值。
四次挥手
- 浏览器向服务器发送TCP数据:FIN(seq=x)
- 服务器向浏览器发送TCP数据: ACK(seq=x+1)
- 服务器向浏览器发送TCP数据:FIN(seq=y)
- 浏览器向服务器发送TCP数据: ACK(seq=y+1)
问:为什么2、3步骤不合起来呢? 答:因为2、3中间服务器可能还有数据要发送,不能提前发送FIN。
具体:
- 客户端发送一个FIN段,并包含接收者看到自己当前的序列号x,同时还包含一个ACK表示确认对方最近一次发过来的数据。
- 服务端将x值加1作为ACK序号值,表明收到了上一个包。这时上层的应用程序会被告知另一端发起了关闭操作,通常浙江引起应用程序发起自己的关闭操作。
- 服务端发起自己的FIN段,ACK=x+1,seq=y
- 客户端确认 ACK=y+1
为什么建立连接是三次握手,而关闭连接是四次挥手呢?
这是因为服务端在LISTEN状态下,收到建立连接的SYN报文后,把ACK和SYN放在一个报文里发送给客户端。而关闭连接后,当收到对方的FIN报文时,仅仅表示对方不再发送数据了但是还是能接收数据,己方是否现在关闭发送数据通道,需要上层应用来决定,因此,己方ACK和FIN一般都会分开发送。
ISN是什么(了解即可)
三次握手的一个重要功能是客户端和服务端交换ISN(Initial Sequence Number),以便让对方知道接下来接收数据的时候如何按序列号组装数据。