三次握手&&四次挥手

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了三次握手&&四次挥手相关的知识,希望对你有一定的参考价值。

参考技术A

  TCP是面向连接的协议。传输连接是用来传送TCP报文的,TCP连接传输的三个阶段分别为: 连接建立、数据传送和连接释放。

  TCP连接的建立采用 客户服务器模式 。主动发起连接建立的应用进程叫做客户,而被动等待连接建立的应用进程叫做服务器。

  TCP建立连接的过程叫做握手,握手需要在客户和服务器之间交换三个TCP报文段,三次握手的过程如下图所示。

  (2) 第二次握手 :服务器收到 SYN报文段后,如同意连接,则服务器会为该TCP连接 分配缓存和变量 ,并向客户端返回 确认报文段 ,在确认报文段中同步位 SYN = 1 和 确认位 ACK = 1,确认号 ack = x + 1,同时也为自己选择一个初始序号 seq = y。这时TCP服务器进程进入 同步收到(SYN-RCVD) 状态。

  (3) 第三次握手 :客户进程在收到服务器进程的确认报文后,客户端为该TCP连接 分配缓存和变量 ,并向服务器端返回一个报文段,这个报文段是对服务器确认报文段进行确认,该报文段中 ACK = 1,确认号 seq = y + 1,而自己序号为 x + 1(即第二次握手服务器确认报文段的确认号)。客户端在发送ACK报文段后进入 已建立连接(ESTABLISHED) 状态,这时TCP连接已经建立。

  当服务器收到客户端的确认后,也进入 ESTABLISHED 状态。

  这样选择序号的目的是为了 防止由于网络路由TCP报文段可能存在延迟抵达与排序混乱的问题,从而而导致某个连接的一方对它作错误的解释
  下图表示了建立连接使用固定的序号存在的问题:

  由于一个TCP连接是被一对端点所表示的,其中包括2个IP地址和2个端口号构成的4元组,因此即便是同一个连接也会出现不同的实例,如果连接由于某个报文段长时间延迟而关闭,然后又以相同的4元组被重新打开,那么可以相信延迟的报文段又会被视为有效据重新进入新连接的数据流中,这就会导致数据乱序问题。

  为了避免上述的问题, 避免连接实例间的序号重叠可以将风险降至最低

  如前文所述,一个TCP报文段只有同时具备连接的4元组与当前活动窗口的序列号,才会在通信过程中被对方认为是正确的。然而,这也反应了TCP连接的脆弱性:如果选择合适的序列号、IP地址和端口号,那么任何人都能伪造一个TCP报文段,从而打断TCP的正常连接。所以使用初始化序号的方式(通常随机生成序号)使得序列号变得难猜,或者使用加密来避免利用这种缺点被攻击。

  所以,可以明白在建立TCP连接时,客户端和服务器端初始化序列号,就避免了上述的问题。前面说过,TCP序号占32位,范围是0~2 32 - 1,并且可以重用。

  假如 第一次握手可以携带数据的话,如果有人使用伪TCP报文段恶意攻击服务器,那么每次都在第一次握手中的SYN报文中携带大量的数据,因为它不会理会服务器的发送和接收能力是否正常,不断地给服务器重复发送这样携带大量数据的SYN报文,这会导致服务器需要花费大量的时间和内存来接收这些报文数据,这会将导致服务器连接资源和内存消耗殆尽。

  所以,之所以第一次握手不能携带数据,其中的一个原因就是 避免让服务器受到攻击 。而对于第三次握手,此时客户端已经建立了连接,通过前两次已经知道了服务器的接收正常,并且也知道了服务器的接收能力是多少,所以可以携带数据。

  根据前面描述,在第一次握手,客户端向服务发送建立连接请求,第二次握手,服务器同意建立连接,并向客户端返回一个确认报文,至此客户端已经知道了服务器同意建立连接,为什么客户端还需要对服务器的允许连接报文段进行确认?

  第三个ACK报文段的目的简单来说主要是为了 实现可靠数据传输

   三次握手的目的不仅在于让通信双方了解一个连接正在建立,还在于利用数据包的选项来承载特殊的信息,交换初始序列号(Initial Sequence,ISN) 。为了实现可靠传输,TCP协议通信双方,都必须维护一个序列号,以标识发送出去的数据报中,哪些是已经被对方收到的。三次握手的过程是通信双方想要告知序列号起始值,并确认已经收到序列号的必经过程。

  如上图,在两次握手过程中,通信双方都随机选择了自己的初始段序号,并且第二次握手的时候客户端收到了自己的确认序号,确认了自己的序列号,而服务器端还没有确认自己的序列号,没有收到确认序号, 如果这时候两次握手下就进行数据传递, 序号没有同步,数据就会乱序。即如果只是两次握手,最多只有客户端的起始序列号能被确认,而服务器断的序列号则得不到确认。

  在三次握手的过程中,服务器为了响应一个受到的SYN报文段,会分配并初始化连接变量和缓存,然后服务器发送一个SYNACK报文段进行响应,并等待客户端的ACK报文段。如果客户不发送ACK来完成该三次握手的第三步,最终(通常在一分多钟之后)服务器将终止该半开连接并回收资源。

  这种TCP连接管理协议的特性就会有这样一个漏洞,攻击者发送大量的TCP SYN报文段,而不完成第三次握手的步骤。随着这种SYN报文段的不断到来,服务器不断为这些半开连接分配资源,从而导致服务器连接资源被消耗殆尽。这种攻击就是 SYN泛供攻击

  为了应对这种攻击,现在有一种有效的防御系统,称为 SYN cookie 。SYN cookie的工作方式如下:

  连接释放的四次挥手过程如下图所示:

  (2) 第二次挥手 :服务器收到连接释放报文段后即发出确认,确认为ACK = 1,确认号为ack = u + 1,序号seq = v(其值是服务器前面已传送过的数据最后一个字节的序号加1),然后服务器就进入了 关闭等待(CLOSE-WAIT) 状态。

  (3) 第三次挥手 :如果此时服务器没有数据要发送了,此时服务器向客户端发出 连接释放报文段 ,其FIN = 1,假设器序号为seq = w(在半关闭状态下服务器可能又发送了一些数据),服务器必须重复上次以发送的确认号ack = u + 1(因为客户端没有向服务器发送过数据,所以确认号和上次一致)。这时,服务器进入 最后确认(LAST-ACK) 状态,等待客户端的确认。

  (4) 第四次挥手 :客户端在收到服务器端发出的连接释放报文段后,必须对此发出确认,在确认报文段中将ACK置位1,确认号ack = w + 1,而自己的序号为seq = u + 1。之后客户端进入 时间等待(TIME-WAIT) 状态。在经过 时间等待计时器 设置的时间 2MSL 后,客户端才进入 关闭(CLOSE) 状态

  这是为了 保证客户端发送的最后一个ACK报文段能够到达服务器端。

  客户端发送的ACK报文段可能丢失,因而使服务器收不到对自己已发送的释放连接报文段的确认。服务器会重传连接释放报文段,重新启动2MSL计时器,最终,客户端和服务器端都能进入CLOSE状态。

  在建立连接时,服务器端处于LISTEN状态时,当收到SYN报文段的建立连接请求后,它可以把ACK报文段和SYN报文段(ACK报文段起确认作用,即确认客户端的连接建立请求;SYN报文段起同步作用)放在一起发送,所以在连接建立时四次握手(即第二次握手时,服务器的ACK报文段和SYN报文段分开发送)可以合并为三次握手。

  而在释放连接时需要四次是因为 TCP连接的半关闭造成的 。由于TCP是 全双工 的(即数据可在两个方向上同时传递),因此,每个方向都必须要单独进行关闭,这个单方向的关闭就叫 半关闭 。在关闭连接时,当服务器收到客户端的FIN报文通知时,它仅仅表示客户端没有数据发送服务器了;但服务器未必将所有的数据都全部发送给了客户端,所以服务器端未必马上也要关闭连接,也即服务器端可能还需要发送一些数据给客户端之后,再发送FIN报文给客户端来表示现在可以关闭连接了,所以 它这里的ACK报文和FIN报文多数情况下都是分开发送的 ,这也是为什么释放连接时需要交换四次报文了。

TCP报文格式,TCP的三次握手和四次挥手&hosts文件

1.TCP报文格式

TCP报头中的源端口号和目的端口号IP数据报中的源IP与目的IP唯一确定一条TCP连接

序号(4字节=32):

    37 59 56 75

    用来标识TCP发端向TCP收端发送的数据字节流

确认序号(4字节=32):

    由于该报文为SYN报文,ACK标志为0,故没有确认序号(ACK标志为1时确认序号才有效)TCP协议规定,只有ACK=1时有效,也规定连接建立后所有发送的报文的ACK必须为1

    一旦连接建立,该值将始终发送(同ACK标志)

头部长度:该字段占用4位,用来表示报文首部的长度,单位是4Byte。如:headLen = ((packet[12]>>4)&0x0F)*4;

预留6位:长度为6位,作为保留字段,暂时没有什么用处。

 

URG:长1位,表示紧急指针字段有效;

ACK:长1位,置位表示确认号字段有效;TCP协议规定,只有ACK=1时有效,也规定连接建立后所有发送的报文的ACK必须为1

PSH:长1位,表示当前报文需要请求推(push)操作;

RST:长1位,置位表示复位TCP连接;

SYN:长1位,在连接建立时用来同步序号。当SYN=1而ACK=0时,表明这是一个连接请求报文。对方若同意建立连接,则应在响应报文中使SYN=1和ACK=1. 因此,SYN置1就表示这是一个连接请求或连接接受报文。

FIN:长1位,用于释放TCP连接时标识发送方比特流结束即完,终结的意思用来释放一个连接。当 FIN = 1 时,表明此报文段的发送方的数据已经发送完毕并要求释放连接。

窗口大小:长度为16位,2个字节。

校验和:长度为16位,2个字节。

紧急指针:长度为16位,2个字节。

以上是TCP包头必须要有的字段,也称固有字段,长度为20个字节。

 

2.TCP三次握手

TCP怎样才能保证可靠的传输任务,就是通过三次握手

首先由Client发出请求连接即 SYN=1 ACK=0  (请看头字段的介绍), TCP规定SYN=1时不能携带数据,但要消耗一个序号,因此声明自己的序号是 seq=x

然后 Server 进行回复确认,即 SYN=1 ACK=1 seq=y, ack=x+1,

再然后 Client 再进行一次确认,但不用SYN 了,这时即为 ACK=1, seq=x+1, ack=y+1.

 

3.TCP四次挥手

  当客户A 没有东西要发送时就要释放 A 这边的连接,A会发送一个报文(没有数据),其中 FIN 设置为1,  服务器B收到后会给应用程序一个信,这时A那边的连接已经关闭,即A不再发送信息(但仍可接收信息)。

  A收到B的确认后进入等待状态,等待B请求释放连接, B数据发送完成后就向A请求连接释放,也是用FIN=1 表示, 并且用 ack = u+1(如图), A收到后回复一个确认信息,并进入 TIME_WAIT 状态, 等待 2MSL 时间。

为什么要等待呢?

为了这种情况: B向A发送 FIN = 1 的释放连接请求,但这个报文丢失了, A没有接到不会发送确认信息B 超时会重传,这时A在 WAIT_TIME 还能够接收到这个请求,这时再回复一个确认就行了。(A收到 FIN = 1 的请求后 WAIT_TIME会重新记时)

另外服务器B存在一个保活状态,即如果A突然故障死机了,那B那边的连接资源什么时候能释放呢?  就是保活时间到了后,B会发送探测信息, 以决定是否释放连接。

 注意:中断连接端可以是Client端,也可以是Server端。

来个通俗版的解释:

假设Client端发起中断连接请求,也就是发送FIN报文。Server端接到FIN报文后,意思是说"我Client端没有数据要发给你了",但是如果你还有数据没有发送完成,则不必急着关闭Socket,可以继续发送数据。所以你先发送ACK,"告诉Client端,你的请求我收到了,但是我还没准备好,请继续你等我的消息"。这个时候Client端就进入FIN_WAIT状态,继续等待Server端的FIN报文。当Server端确定数据已发送完成,则向Client端发送FIN报文,"告诉Client端,好了,我这边数据发完了,准备好关闭连接了"。Client端收到FIN报文后,"就知道可以关闭连接了,但是他还是不相信网络,怕Server端不知道要关闭,所以发送ACK后进入TIME_WAIT状态,如果Server端没有收到ACK则可以重传。“,Server端收到ACK后,"就知道可以断开连接了"。Client端等待了2MSL后依然没有收到回复,则证明Server端已正常关闭,那好,我Client端也可以关闭连接了Ok,TCP连接就这样关闭了!(是服务端先关闭,后客户端关闭

【问题1】为什么连接的时候是三次握手,关闭的时候却是四次握手?
答:因为当Server端收到Client端的SYN连接请求报文后,可以直接发送SYN+ACK报文。其中ACK报文是用来应答的,SYN报文是用来同步的。但是关闭连接时,当Server端收到FIN报文时,很可能并不会立即关闭SOCKET,所以只能先回复一个ACK报文,告诉Client端,"你发的FIN报文我收到了"。只有等到我Server端所有的报文都发送完了,我才能发送FIN报文,因此不能一起发送。故需要四步握手。

【问题2】为什么TIME_WAIT状态需要经过2MSL(最大报文段生存时间)才能返回到CLOSE状态?

答:虽然按道理,四个报文都发送完毕,我们可以直接进入CLOSE状态了,但是我们必须假象网络是不可靠的,有可以最后一个ACK丢失。所以TIME_WAIT状态就是用来重发可能丢失的ACK报文。

整个客户端所经历的状态:

整个服务端经历的状态:

栗子1:

TCP链接中主动断开链接netstat观察可能出现的状态流转是:CD

  A.ESTABLISHED->CLOSE_WAIT->TIME_WAIT->CLOSED

  B.ESTABLISHED->TIME_WAIT->CLOSE_WAIT->CLOSED

  C.ESTABLISHED->FIN_WAIT_1->FIN_WAIT_2->TIME_WAIT->CLOSED

  D.ESTABLISHED->FIN_WAIT_1->TIME_WAIT->CLOSED

栗子2:

一条tcp连接,主动关闭的一方不可能出现的连接状态是()A

  A.CLOSE_WAIT

  B.FIN_WAIT2

  C.TIME_WAIT

  D.FIN_WAIT1

4.关于Host文件

hosts文件 是一个用于储存计算机网络中各节点信息的计算机文件。
这个文件负责将主机名称映射到相应的IP地址 。
hosts文件通常用于补充或取代网络中 DNS 的功能。
和DNS不同的是,计算机的用户可以直接对hosts文件进行控制。

host文件一个没有扩展名的系统文件,其作用就是用来存储一些常用的网络域名和与其对应的ip地址,当用户输入一个需要登录的网址时,系统就会先去host文件中查找,如果找到了就立即打开该网址,如果找不到就去DNS域名解析服务器中查找。

参考文档:http://blog.csdn.net/imilli/article/details/50620104

 

以上是关于三次握手&&四次挥手的主要内容,如果未能解决你的问题,请参考以下文章

三次握手 && 四次挥手

如何应对考官的TCP三次握手&四次挥手提问?

浅谈“三次握手与四次挥手”

网络 之 三次握手&四次挥手 介绍

[svc]tcp三次握手四次挥手&tcp的11种状态(半连接)&tcp的time-wait

tcpdump命令和三次握手四次挥手