您的位置:首页 > 理论基础 > 计算机网络

网络基础 — 浅析TCP协议中的3次握手和4次挥手

2017-07-20 17:03 357 查看

浅析TCP协议中的3次握手和4次挥手 

我们都知道TCP协议很稳健很安全,虽然相对UDP来说传输速度不怎么样的快,但是TCP协议提供可靠性也是他为什么是主流协议的原因我们今天就是来
瞧瞧它的可靠性是怎么什么原理,让我们也学习学习.首先我们明白TCP可靠性基于7个方面:
1.TCP提供请求问答机制.  *今天的重点*2.TCP保证数据的按序到达.3.TCP提供丢包重传机制.4.TCP面向链接保证可靠性.5.TCP拥有众多的定时器(例如超时重传定时器).6.TCP进行流量控制.7.TCP逻辑上有网络避免拥挤算法.

接下来我们开始真正的了解TCP协议的结构和机制,首先我们了解TCP协议段格式,再然后我们来进入我们今天的硬菜大主题,TCP协议的三次握手和四
次挥手,了解它的原理,明白TCP协议的通信过程。。。。

TCP协议段格式

                                                                                                  

TCP协议段格式:





16位源端口号:标识发送报文的计算机端口或进程。一个 TCP 报文段必须包括源端口号,使目的主机知道应该向何处发送确认报文。16位目的端口号:标识接收报文的目的主机的端口或进程32位序号: 用于标识每个报文段,使目的主机可确认已收到指定报文段中的数据。当源主机用于多个报文段发送一个报文时,即使这些报文到达目的主机的顺序不一样,序列号也可以使目的主机按顺序排列它们。在 SYN 标志未置位时,该字段指示了用户数据区中第一个字节的序号;在 SYN 标志置位时,该字段指示的是初始发送的序列号。32位确认序号:目的主机返回确认号,使源主机知道某个或几个报文段已被接收。如果 ACK 控制位被设置为 1,则该字段有效。确认号等于顺序接收到的最后一个报文段的序号加 1,这也是目的主机希望下次接收的报文段的序号值。返回确认号后,计算机认为已接收到小于该确认号的所有数据。4位首部长度: TCP 报文段的数据起始处距离 TCP 报文段的起始处有多远,即首部长度。保留位:由跟在数据偏移字段后的 6 位构成, 全部为 0 。URG:此位置 1,表明紧急指针字段有效,它告诉系统此报文段中有紧急数据,应尽快传送ACK:仅当 ACK = 1 时确认号字段才有效,TCP 规定,在连接建立后所有传达的报文段都必须把 ACK 置 1。PSH:当两个应用进程进行交互式的通信时,有时在一端的应用进程希望在键入一个命令后立即就能够收到对方的响应。在这种情况下,TCP 就可以使用推送(push)操作,这时,发送方 TCP 把 PSH 置 1 ,并立即创建一个报文段发送出去,接收方收到 PSH = 1 的报文段,就尽快地(即“推送”向前)交付给接收应用进程,而不再等到整个缓存都填满后再向上交付。
RST:置1时重建连接。如果接收到RST位时候,通常发生了某些错误。

SYN:仅在三次握手建立 TCP 连接时有效。当 SYN = 1而 ACK = 0时,表明这是一个连接请求报文段,对方若同意建立连接,则应在相
的报文段中使用 SYN = 1和ACK = 1。因此SYN置1就表示这是一个连接请求或连接接受报文。
FIN:用来释放一个连接。当 FIN = 1时,表明此报文段的发送方的数据已经发送完毕,并要求释放运输连接。
16位窗口大小:此字段用来进行流量控制,这个值是本机期望一次接收的字节数,即发送数据的窗口大小。16位校验和:源主机和目的主机根据 TCP 报文段以及伪报头的内容计算校验和。在伪报头中存放着来自 IP 报头以及 TCP 报文段长度信息。与 UDP 一样,伪报头并不在网络中传输,并且在校验和中包含伪报头的目的是为了防止目的主机错误地接收存在路由的错误数据报。16位紧急指针:仅在 URG = 1 时才有意义,它指出本报文段中的紧急数据的字节数(紧急数据结束后就是普通数据),即指出了紧急数据的末尾在报文中的位置,注意:即使窗口为零时也可发送紧急数据。
如果 URG 为 1 ,则紧急指针标志着紧急数据的结束。其值是紧急数据最后 1 字节的序号,表示报文段序号的偏移量。例如,如果报文段
的序号是 1000,前 8 个字节都是紧急数据,那么紧急指针就是 8 。紧急指针一般用途是使用户可中止进程。



三次握手基本流程

                                                                                                      


基本过程:                     




第一次握手:客户端将SYN设置为1,表示要建立一个新的连接,并随机产生一个序列值Seq=M,并将该数据包发给服务器客户端进入FIN_SEND状态;第二次握手:服务器收到数据包后由标志位SYN=1知道客户端要建立一个连接,服务器将确认ACK和SYN都置为1,ack=M+1并随机产生一个Seq=N,并将该数据包发给客户端,服务器进入SYN_RCVD状态;第三次握手:客户端收到确认后,检查ack是否为M+1,ACK是否为1,服务器有时候不同意建立一个连接(有可能达到了服务器建立客户端的上线),么这里的ACK=0,表示无效,如果正确,则建立成功,客户端和服务器都进入ESTABLISHED状态,完成三次握手,随后服务器和客户端之间就开始传输数据了!这就是三次握手!!!!

                                                                                                                   

可能这里就会有人疑惑了,为什么是三次握手而不是两次呢? 按道理讲两次握手其实是可以的进行传输的,但是为什么三次?

举个例子,这里建立连接的过程是利用客户服务器模式,假设主机A为客户端,主机B为服务器端。采用三次握手是为了防止失效的连接请求报文段突然又传送到主机B,因而产生主机B的资源浪费。失效的连接请求报文段是指:主机A发出的连接请求后没有收到主机B的回复确认,于是经过一段时间后,主机A又重新向主机B发送连接请求,且建立成功,顺序完成数据传输。考虑这样一种特殊情况,主机A第一次发送的连接请求并没有丢失,而是因为网络节点导致延迟达到主机B,主机B以为是主机A又发起的新连接,于是主机B同意连接,并向主机A发回确认,但是此时主机A根本不会理会,主机B就一直在等待主机A发送数据,导致主机B的资源浪费。我们考虑一下最特殊的情况,就是主机A发了无数个请求,主机B也确认了无数遍,然后当B主机确认后是有代价的他会开辟一段空间等待主机A往那里面填数据.但是A主机就是不发数据.这样就是造成严重的资源占用.这样很容易被别人抓住这个问题攻击你,所以三次握手的重要性一下就突出来了.

但是TCP的三次握手真的就那么坚不可摧吗?
SYN攻击->在第二次握手之后,收到客户端的ACK之前的TCP连接属于半连接(half-open-connect),此时服务器处于SYN_RECV状态,当收到客户端的ACK后才是establish状态,SYN攻击就是客户端在短时间内伪造大量的不存在的地址,并向服务器不断的发送SYN包,服务器恢复确认包,并等待客户端的恢复,因为那些IP是不存在的,所以服务器需要不断的重发直至超时,这些伪造的SYN包占用未连接队列,导致正常请求的SYN请求队列满而被丢弃,从而引起系统的瘫痪和拥塞。SYN攻击是一种典型的DDOS攻击,检测的方式也十分简单:即当服务器上有大量的半连接状态的源IP地址是随机的,那说明该机器遭受SYN攻击了。

四次挥手的基本过程

                                                                                                      

 基本过程:

                         





第一次挥手:客户端发起一个FIN和一个Seq=M,要求关闭客户端到服务器之间的数据传递,客户端进入FIN_WAIT1状态;

第二次挥手:服务器收到FIN后,发送一个ACK=1,和ack=M+1表示知道了,进入CLOSE_WAIT状态;

第三次挥手:当服务器的数据传递完后,再发送一个FIN和一个Seq=N来确定断开连接,等待最后一个ACK的到来;

第四次挥手:此时一直等待的客户端接收到FIN信号表示服务器也要断开了,没数据传送了,变发送一个ACK和ack=N+1,主动断开了                         然后服务器也就被动断开了;这就是4次挥手的基本过程! 有木有觉得突然就很清晰,之前一直觉得好难哈哈.现在有一个问题,讲道理我们3次握手就建立了连接,但是我断开的时候用了4次挥手,这不符合物理守恒定律啊,这是为什么?
这是因为服务器在listen的状态下,收到建立连接请求的SYN报文后,把SYN和ACK放在一个报文里发送给客户端。而关闭连接时,由于TCP属于全双工工作方式,它把FIN和ACK分了两次发,也就是在客户端请求断开时,服务器可以立即中断,也可以把自己要发给客户端的数据发送完以后在发送FIN被动中断。主要是看服务器还有没有数据要发送,如果服务器也是将FIN和ACK直接一起发给客户端,那么也就是三次挥手了!!

最后一个问题为什么TIME_WAIT状态还需要等2MSL后才能返回到CLOSED状态? TCP的可靠性会根据请求问答机制,四次挥手的时候,最后一条报文是否到达是不可靠的,也就是我们都已经同意关闭连接了,服务器已经向客户端发送了FIN,这时候服务器就等着收到最后一个ACK然后断开连接,但是客户端发送的最后一条报文完全是有可能没有发送到服务器的,服务器有段时间没有收到客户端发送回来的ACK,它肯定会重新发送一次FIN,如果这个时候客户端发送完ACK就直接切为CLOSED的状态,肯定就收不到服务器发过来的FIN了,所以TIME_WAIT状态多等2MSL的作用就是重新发送可能丢失的最后一个ACK报文,完成断开连接.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: