TCP的三次握手

1、概述

TCP三次握手是浏览器和服务器建立连接的方式,目的是为了使二者能够建立连接,便于后续的数据交互传输。

第一次握手:浏览器向服务器发起建立连接的请求。

第二次握手:服务器告诉浏览器,我同意你的连接请求,同时我也向你发起建立连接的请求。

第三次握手:浏览器也告诉服务器,我同意建立连接。

至此,双方都知道对方同意建立连接,并准备好了进行数据传输。


2、具体过程

image

参数说明

SYN:

  • TCP报文中的标志位字段之一。
  • 在建立连接时使用,用来同步序号。
    • 当 SYN=1,ACK=0 时,表示这是一个请求建立连接的报文段。
    • 当 SYN=1,ACK=1 时,表示对方同意建立连接。
    • SYN=1 时,说明这是一个请求建立连接或同意建立连接的报文。只有在前两次握手中 SYN 才为 1。

ACK:

  • TCP报文中的标志位字段之一。

  • 表示前面的确认号字段是否有效,ACK=1 时表示有效。只有当 ACK=1 时,前面的确认号字段才有效。

  • TCP 规定,连接建立后,ACK 必须为 1。

seq:

  • TCP报文中的序列号字段。
  • 占32位(bit),表示本报文段所发送数据的第一个字节的编号。在TCP连接中,所传送的字节流的每一个字节都会按顺序编号。

ack:

  • TCP报文中的确认号字段。
  • 占32位(bit),表示接收方期望收到发送方下一个报文段的第一个字节数据的编号。

0、初始状态

服务端监听某个端口,处于 LISTEN 状态。


1、客户端发送TCP连接请求

客户端会随机一个初始序列号seq=x(client_isn),设置SYN=1 ,表示这是SYN握手报文。

然后就可以把这个 SYN 报文发送给服务端了,表示向服务端发起连接,之后客户端处于 同步已发送状态。


2、服务端发送针对TCP连接请求的确认

服务端收到客户端的 SYN 报文后,也随机一个初始序列号seq=y(server_isn)

设置ack=x+1,表示收到了客户端的x之前的数据,希望客户端下次发送的数据从x+1开始。

设置 SYN=1 和 ACK=1。表示这是一个SYN握手和ACK确认应答报文。

最后把该报文发给客户端,该报文也不包含应用层数据,之后服务端处于同步已接收状态。


3、客户端发送确认的确认

客户端收到服务端报文后,还要向服务端回应最后一个应答报文。

将ACK置为 1 ,表示这是一个应答报文。

设置ack=y+1 ,表示收到了服务器的y之前的数据,希望服务器下次发送的数据从y+1开始。

最后把报文发送给服务端,这次报文可以携带数据,之后客户端处于连接已建立状态。

服务器收到客户端的应答报文后,也进入连接已建立状态。


3、为什么是三次握手?

3.1、主要原因是为了防止历史连接。

三次握手的时候,如果网络拥堵,第一次握手的SYN包没能到达服务端,那么客户端就会连续发送多次SYN建立连接的报文,那就有可能出现一个【后发送的SYN报文】比一个【早发送的SYN报文】早到达服务端。

那么此时服务端就会回一个 SYN + ACK 报文给客户端;

  • 如果是两次握手连接,就不能判断当前的连接是否是历史连接,导致错误。
  • 如果是三次握手连接,客户端收到后可以根据自身的上下文,判断这是一个历史连接(序列号过期或超时),那么客户端就会发送 RST 报文给服务端,中止这一次连接。

3.2、三次握手可以避免资源浪费

如果只有两次握手,当客户端的 SYN 请求连接在网络中阻塞,客户端没有接收到 ACK 报文,就会重新发送 SYN。

如果是三次握手,第三次握手时服务器可以得到客户端的ack,知道连接已成功建立。

如果没有第三次握手,服务器不清楚客户端是否收到了自己发送的建立连接的 ACK 确认信号,所以每收到一个 SYN 就只能先主动建立一个连接。

如果客户端的 SYN 阻塞了,重复发送多次 SYN 报文,那么服务器在收到请求后就会建立多个冗余的无效链接,造成不必要的资源浪费。


学习参考:

posted @ 2022-11-21 10:49  笔下洛璃  阅读(243)  评论(0编辑  收藏  举报