在了解TCP/IP协议三次握手、四次挥手之前,先对TCP报文格式进行简单了解
TCP报文格式
中文版:
英文版:
关于三次握手、四次挥手需要了解的TCP报文格式部分
序号是随机生成的一串数字,代表当前的报文序号是多少,叫做seq(sequence number)。
确认序号是对上一条报文的信息,进行一个确认,叫做ack(acknowledgment number)。
红色圈出来的部分,每一行代表4个字节,因为1个字节=8位,所以32位就是4个字节,我们可以简单的把这些字节想象成0101010…
所以在第四行,不管是ACK或者SYN或者FIN,都是只占一个字节,为什么呢?首先我们知道每一行就是32位,第四行的4位首部长度+保留6(位)+16位窗口大小=4+6+16=26,那么剩下的就只有32-26=6位,所以每个标志位表示1位,ACK或者SYN或者FIN都称为标志位,而6个标志位组成的部分叫控制位。
什么是ACK,SYN,FIN?
- ACK:确认序号标志,当值为1时表示确认号有效,为0表示报文中不含确认信息,忽略确认号字段。
- SYN:同步序号,用于建立连接过程,在连接请求中,SYN=1和ACK=0表示该数据段没有使用捎带的确认域,而连接应答捎带一个确认,即SYN=1和ACK=1。
- FIN:finish标志,用于释放连接,为1时表示发送方已经没有数据发送了,即关闭本方数据流。
什么是三次握手?以及为什么要三次握手?两次不行吗?
首先客户端向服务端发起建立连接的请求,第一步客户端在TCP报文格式中,将SYN值变为1,相当于告诉服务端,我要和你建立连接,随机生成seq值代表当前的报文序号,假设是1000。
当服务端接收到这个请求后,向服务端发起响应,此时服务端发送的TCP报文格式中,SYN的值变成1,随机生成seq值代表当前的报文序号,假设是2000,ACK变成1,相当于告诉客户端,我已经收到了你的请求,ack会变成在之前客户端发送的seq值+1,也就是1000+1=1001。
重点来了,当客户端收到服务端发送的报文,客户端此时可以确定一件事情,就是客户端发送消息和接受消息都是正常的,但是,对于服务端来说,它只知道自己可以成功接受消息,但是自己能不能成功发送消息,并不知道,所以,只有两次握手肯定是不行的,由于TCP/IP协议是一种可靠的传输层通信协议,所以不能让这种情况发生。
由此就有了第三步,客户端发送报文,ack值为2001,ACK值为1,相当于告诉服务端,你发送的消息,我已经收到了,那么当服务端接收到这个报文,就可以确认自己是可以正常的接受消息和发送消息了,这就是三次握手的过程。
什么是四次挥手?
首先客户端发送报文,FIN=1,相当于告诉服务端,我和你断开连接了,seq=2345,这里的seq不是随机生成的,而是由之前一系列操作演变而来的。
当服务端接收到报文,发送报文给客户端,ACK=1,相当于告诉客户端,我收到了你的消息,ack是上一个seq值+1。
然后服务端又会发送报文,FIN=1,相当于告诉客户端,我要和你断开连接了,seq=5555,这里的seq不是随机生成的,而是由之前一系列操作演变而来的。
当客户端收到从服务端发送过来的消息后,发送报文给服务端,ACK=1,相当于告诉服务端,我收到了你的消息,ackack是上一个seq值+1,至此客户端和服务端断开连接,这就是四次挥手过程。
那么可能有个问题,第二步和第三步可以合并成一步吗?
答案是不行的,因为TCP/IP协议是一种可靠的传输层通信协议,当第一步的时候,服务端收到了来自客户端的报文,此时只能说明客户端已经做好了与服务端断开的准备,但是服务端有没有做好准备,客户端并不知道,所以服务端选择先发送ACK=1,先告诉客户端,我收到了你的消息,等我把事情处理好之后,再跟你断开,此时客户端收到消息就会等,直到服务端发送FIN=1,客户端就确认服务端已经做好了断开的准备了。
都看到这里了,不考虑点个赞再走嘛?