码迷,mamicode.com
首页 > Web开发 > 详细

HTTP 三次握手

时间:2019-10-21 16:12:31      阅读:95      评论:0      收藏:0      [点我收藏+]

标签:错误   set   client   info   完成   时间   前置   发送   idt   

技术图片

 

 前置:

1、Http请求是基于Tcp connection这个链接的

2、位码即tcp标志位,有6种标示:

SYN(synchronous建立联机) 、ACK(acknowledgement 确认)、 PSH(push传送)

FIN(finish结束)、RST(reset重置)、 URG(urgent紧急)

Sequence number(顺序号码) 

Acknowledge number(确认号码)

  1. SYN (同步序列编号):是 TCP/IP 建立连接时使用的握手信号。TCP 连接的第一个包,非常小的一种数据包。在客户机和服务器之间建立正常的 TCP 网络连接时,客户机首先发出一个 SYN 消息,服务器使用 SYN + ACK 应答表示接收到了这个消息,最后客户机再以 ACK 消息响应。这样在客户机和服务器之间才能建立起可靠的 TCP 连接,数据才可以在客户机和服务器之间传递。

  2. Seq (序号):是 TCP 可靠传输的关键部分。序号是该报文段发送的数据组的第一个字节的序号。在 TCP 传送的流中,每一个字节都有一个序号。比如一个报文段的序号为 300,报文段数据部分共有 100 字节,则下一个报文段的序号为 400 。所以序号确保了 TCP 传输的有序性。

  3. ACK (确认值):仅当 ACK = 1 时,确认号字段才有效。TCP 规定,在连接建立后所有报文的传输都必须把 ACK 置 1 。

  4. Ack (确认号):指明下一个期待收到的字节序号,表明该序号之前的所有数据已经正确无误的收到。确认号只有当 ACK 标志为 1 时才有效。比如建立连接时,SYN 报文的 ACK 标志位为 0 。

状态:

  1. CLOSED:表示初始状态
  2. SYN_SENT:表示客户端已发送 SYN 报文
  3. SYN_RCVD:表示服务器接受到了 SYN 报文
  4. ESTABLISHED:表示连接已经建立

过程:

第一次握手:建立连接时,客户端发送 SYN 到服务器,并进入 SYN_SENT 状态

第二次握手:服务器收到请求后,回送 SYN + ACK 到客户端,此时服务器进入 SYN_RECV 状态;

第三次握手:客户端收到 SYN + ACK 包,向服务器发送确认 ACK 包,客户端进入 ESTABLISHED 状态,服务器收到请求后也进入 ESTABLISHED 状态,完成三次握手,此时 TCP 连接成功,客户端与服务器开始传送数据

第一次握手 (客户端向服务器发送):Client 首先发送一个连接试探,ACK = 0 表示确认号无效,SYN = 1 表示这是一个连接请求或连接接受报文,同时表示这个数据报不能携带数据,seq = x 表示 Client 自己的初始序号( seq = 0 就代表这是第 0 号帧),这时候 Client 进入 SYN_SENT 状态,表示客户端等待服务器的回复

第二次握手 (服务器回复客户端):Server 监听到连接请求报文后,如同意建立连接,则向 Client 发送确认。

TCP 报文首部中的 SYN 和 ACK 都置为 1 ,ack = x + 1表示期望收到对方下一个报文段的第一个数据字节序号是 x + 1 ,同时表明 x 为止的所有数据都已正确收到( ack = 1 其实是 ack = 0 + 1 ,也就是期望客户端的第 1 个帧),seq = y 表示 Server 自己的初始序号( seq = 0 就代表这是服务器这边发出的第 0 号帧)。这时服务器进入 SYN_RCVD 状态,表示服务器已经收到 Client 的连接请求,等待 Client 的确认

第三次握手 (客户端向服务器发送):Client 收到确认后还需再次发送确认,同时携带要发送给 Server 的数据。ACK 置 1 表示确认号 ack = y + 1 有效(代表期望收到服务器的第 1 个帧),Client 自己的序号 seq = x + 1(表示这就是我的第1个帧,相对于第0个帧来说的),一旦收到 Client 的确认之后,这个 TCP 连接就进入 ESTABLISHED 状态,就可以发起 http 请求了

为什么是三次握手

  1. 在第一次通信过程中,A向B发送信息之后,B收到信息后可以确认自己的收信能力和A的发信能力没有问题。
  2. 在第二次通信中,B向A发送信息之后,A可以确认自己的发信能力和B的收信能力没有问题,但是B不知道自己的发信能力到底如何,所以就需要第三次通信。
  3. 在第三次通信中,A向B发送信息之后,B就可以确认自己的发信能力没有问题。

A-->B-->A-->B这样传三次能保证A有发有收,B也有发有收。多一次浪费少一次不够。

所以为什么是三次握手:最主要是防止已过期的连接再次传到被连接的主机

那为什么非要三次呢?怎么觉得两次就可以完成了。那 TCP 为什么非要进行三次连接呢?在谢希仁的《计算机网络》中是这样说的:

为了防止已失效的连接请求报文段突然又传送到了服务端,因而产生错误。

在书中同时举了一个例子,如下:

"已失效的连接请求报文段”的产生在这样一种情况下:

Client 发出的第一个连接请求报文段并没有丢失,而是在某个网络结点长时间的滞留了,以致延误到连接释放以后的某个时间才到达 Server 。本来这是一个早已失效的报文段。但 Server 收到此失效的连接请求报文段后,就误认为是 Client 再次发出的一个新的连接请求。于是就向 Client 发出确认报文段,同意建立连接。假设不采用“三次握手”,那么只要 Server 发出确认,新的连接就建立了。由于现在 Client 并没有发出建立连接的请求,因此不会理睬 Server 的确认,也不会向 Server 发送数据。但 Server 却以为新的运输连接已经建立,并一直等待 Client 发来数据。这样,Server 的很多资源就白白浪费掉了。采用“三次握手”的办法可以防止上述现象发生。例如刚才那种情况,Client 不会向 Server 的确认发出确认。 Server 由于收不到确认,就知道 Client 并没有要求建立连接。"这就很明白了,防止了服务器端的一直等待而浪费资源。

示例分析:

192.168.1.11 为客户端 A,42.121.252.58 为服务器 B。

  1. 客户端请求连接发送 SYN 产生一个为 x = 0 的序号 seq 。
  2. 服务器接受连接,ACK = x + 1 = 1 并产生 y = 0 的序号 seq;发送 SYN ACK seq = 0 ack = 1 到客户端。
  3. 客户端发现服务器接受了连接请求返回了 ack,seq = x;同时接受服务器的请求 ack = y + 1 = 1。
  4. 因为上个传输,只传输了一个 ACK 没有数据,所以看第四条线 seq = 1,ack = 1。

收获:看 2 这个项,发送端的 seq 字段需要接收到服务器段的 ack 才会变化,这个时候 服务器 ack = 客户端 seq 。

所以我才会有下面对 seq 和 ack 的理解。

  • 序号 seq :发送了多少被成功接受数据。
  • 确认号 ack:接受了多少数据。

 

HTTP 三次握手

标签:错误   set   client   info   完成   时间   前置   发送   idt   

原文地址:https://www.cnblogs.com/momo798/p/11713832.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!