天天看点

TCP的三次握手、四次挥手

一、三次握手:

  TCP是面向连接的协议,通过保证建立的双向连接,实现数据的安全稳定传输。三次握手是服务器与客户端建立连接时的过程。在服务器使用accept()函数阻塞等待客户端的连接,当有客户端调用connect()函数时,开始进行三次握手建立连接,成功建立后,accept()函数解阻塞,执行后序的任务。

1、简述这个过程:

  1. 客户端向服务器发送了一个信息,目的告诉服务器,客户端想要建立连接
  2. 服务器给客户端回应一个信息,有两个目的,一是告诉客户端,服务器可以成功收到客户端发送的信息,二是确认客户端可以收到服务器发送的信息
  3. 客户端收到服务器返回的信息后,再次给服务器返回一个信息,目的是告诉服务器,客户端可以成功接收服务器的信息;

2、详述这个过程:

  1. 第一次握手:客户端向服务器发送了一个请求连接报文,报文中重要的有两个数据,一个是SYN=1,这是一个标志符,当SYN=1代表请求建立连接,另一个是seq=x,TCP传输的数据是字节流的,seq是TCP字节流中的一个编号,他也用来区分是哪一个服务器/客户端,所有学习时普遍使用x代表它的值;
  2. 第二次握手:服务器接收到这个请求报文后,准备一个响应报文,报文重要数据主要有4个:ACK=1,ACK也是一个标志符,ACK=1代表确认接收到了来自对方的消息;seq=y,同为字节流中的编号;SYN=1,TCP是建立双向的连接,所有服务器也发送一个请求连接的信息;ack=x+1,ack是对客户端发送的seq的回应,将客户端发送的seq编号加1放在ack回应里发送给客户端;
  3. 第三次握手:客户端收到服务器返回的响应和建立连接请求,目前确定了服务器可以接收到客户端的信息,所以最后一次握手是确定客户端可以收到服务器的地址,这时客户端向服务器发送一个数据包,重要数据有:ACK=1表示可以接收信息;ack=y+1,将服务器的seq加1放到ack中;seq=x+1,表示自己是哪个客户端。

3、为什么是三次握手?

  TCP要建立安全稳定的双向连接,必须保证双方都接接收到来自对方的信息,第一次和第二次确定了服务器可以接收到客户端的信息,第三次确定了客户端可以接收服务器的信息,因此最少是三次。

4、图解三次握手

TCP的三次握手、四次挥手

二、四次挥手

1、简述这个过程

  1. 客户端向服务器发送一个消息,告诉服务器,客户端准备断开连接,并不会在发送数据信息了
  2. 服务器收到客户端的请求,返回一个信息,告诉客户端收到了这个信息
  3. 服务器向客户端发送信息,告诉客户端,服务器准备断开连接
  4. 客户端收到这个信息后,告诉服务器收到了这个信息,此时双方信息确定,断开连接

2、详述这个过程

  1. 客户端调用close()函数,向服务器发送连接释放报文,报文中有两个重要的数据,FIN=1,标志符,FIN=1表示请求断开连接,seq=u,客户端数据字节流的编号
  2. 服务器收到请求报文,recv()函数解阻塞,返回给客户端一个响应,重要数据有:ACK=1,表示可以收到信息;seq=v,服务器字节流数据的编号;ack=u+1,客户端seq加1
  3. 服务器调用close()函数,向客户端发送连接释放报文,报文中的重要数据有:FIN=1,seq=w,ACK=1,ack=u+1
  4. 客户端收到后,回复客户端一个数据包,ACK=1,ack=w+1,seq=u+1

3、为什么是四次?

  为什么握手可以是三次,挥手却是四次?因为中间第二次挥手和第三次挥手的触发条件不同。

  第二次挥手是服务器收到了客户端断开连接的请求,此时recv()解阻塞,发送第三次挥手信息;

  第三次挥手是服务器调用了close(),服务器什么时候调用close()什么时候发送第三次挥手信息;

  所以因为触发的条件不同,前两次确认了客户端的断开,后两次确认了服务器的断开。

4、图解四次挥手

TCP的三次握手、四次挥手

5、断开连接的等待时间

  • 服务器端连接的完全断开,是收到客户端发送的第四次挥手的数据后立刻断开
  • 客户端在发送第四次挥手的数据后,会等待2MSL时间后才会完全断开

2MSL:MSL是最长报文段寿命,2MSL即数据包一去一回的最长时间。

  第三次挥手时,服务器给客户端发送了信息,同时开始了超时时间的倒计时,客户端收到后会返回一个信息给服务器;

  如果此时的网络出现了问题,服务器没有在超时时间内收到客户端的响应,那么服务器就会再次发送信息给客户端

  所以为了双方连接的完全断开,客户端不能再发送第四次挥手信息后直接关闭,需要等待2MSL时间,即从客户端发送第四次挥手信息开始,到服务器再次发送了一个请求信息的最长时间;

  只要服务器收到了来自客户端的最后确认信息,就代表双方可以完全断开连接,此时服务器先断开;

  客户端只要在2MSL时间内没有收到服务器的信息,就代表服务器已经收到了,所有,客户端在2MSL时间后断开连接。

6、图解2MSL 等待时间

TCP的三次握手、四次挥手

三、使用tcpdump抓取三次握手、四次挥手的报文

准备三个终端

$ # 第一个终端:启动抓包程序
$ sudo tcpdump -# -S -n -i lo0 tcp and host 127.0.0.1 and port 8000
$ # 第二个终端:启动服务端程序
$ nc -l 8000
$ # 第三个终端:启动客户端程序,发送请求
$ nc localhost 8000
           

此时第一个终端中就显示了三次握手的报文信息:

TCP的三次握手、四次挥手

将第三个终端Ctrl+C,客户端发起关闭,即可在第一个终端中显示四次挥手报文信息:

TCP的三次握手、四次挥手

继续阅读