TCP三次握手四次挥手,重理解

多次会看TCP的三次握手四次挥手,感觉理解的都很表面,最近参考了其他博主的博文,做了下总结方便理解,如有哪里理解错误,欢迎指出:

TCP首部参考图 :

 

一、一些基本概念,帮助理解,已了解可向后看:

           首先我们知道tcp传输控制协议,它属于传输层协议用于提供portport面向连接的可靠的字节流传输是建立在物理层、数据链路层、网络层之上的协议,而底层的网络是不可靠的,可能路由出现问题、网关出现问题、网线出现问题,这些问题我们是没办法保证的,主机A没办法保证自己发送出来的消息主机B一定可以收到,所以tcp建立了一种反馈机制,做出的行为要得到反馈,即ACK,相对的保证了在不可靠的网络层构建中建立了可靠地传输层;

 

tcp中的六个标志位:

 

字段

含义

URG

紧急指针是否有效,为1,表示某一位需要被优先处理

ACK

确认号是否有效 为1,有效

SYN

请求建立连接,并在其序列号的字段进行序列号的初始值设定,建立连接 设为1

FIN

释放连接

PSH

提示接收端应用程序立即从TCP缓冲区把数据读走

RST

重新建立连接

序列号seq:用来标记数据段的顺序,

确认号ack:期待收到对方下一个报文段的序号,一般是当前报文段的最后一个字节的编号+1即为确认号

 

 

 

二、三次握手:

 

第一次握手:主机A向主机B发送一个SYN有效同步信息,同时随机生成seq=x,此时主机A进入SYN-SENT同步发送状态,等待服务器确认,(SYN=1,seq=x)

第二次握手:主机B收到主机A发送的SYN信息,会回送主机A一个ACK确认有效信息ack=x+1,ACK=1),同时发送自己的SYN同步信息,随机seq=y,即发送ACK+SYN信息给主机A,此时主机B进入SYN-RCVD同步收到状态;

第三次握手:主机A收到主机B发送的信息包,确认信息无误后,回送给主机BACK确认有效信息即(seq=x+1,ack=y+1)

 

 

为什么是三次握手而不是两次握手?

 

其实TCP采用三次握手的原因很简单:

1、为了实现可靠地数据传输,TCP协议的通信双方,都必须维护一个序列号,标识自己发送出去的数据包中,那些事已经被对方收到的。三次握手的过程即是通信双方相互告知序列号起始值,并确认对方已经收到了序列号起始值的必经之路,

2、如果是两次握手,至多只有连接的发起方的起始值序列号能被确认,另一方的序列号得不到确认

例子(可选看):

如果是两次连接,主机A发送SYN确认信息给主机B,主机B收到SYN信息后回送ACK确认信息,此时主机B是认为建立连接成功,可以发送数据。在主机B回送的确认信息丢失的情况下,主机A是认为建立不成功的,会忽略主机B发送的数据信息,只会等待确认信息,此时,主机B发送数据得不到回复就会形成死锁的情况;

 

四次挥手

 

 

由于TCP连接是全双工的,因此,每个方向都必须要单独进行关闭,当一方完成数据发送任务后,发送一个FIN来终止这一方向的连接,收到一个FIN只是意味着这一方向上没有数据流动了,即不会再收到数据了,但是在这个TCP连接上仍然能够发送数据,直到这一方向也发送了FIN。首先进行关闭的一方将执行主动关闭,而另一方则执行被动关闭,

 

第一次挥手:主机A向主机B发送FIN释放信息,表示数据发送完毕,请求关闭主机A到主机B的数据传送,主机A进入 FIN_WAIT_1状态;

第二次挥手:主机B收到主机A的FIN请求,发送给主机A一个ACK确认信息,主机B进入CLOSE_WAIT状态;

此时不能同时向主机A发送FIN释放请求,需要等待数据发送完后在发送FIN

第三次挥手:主机B向主机A发送FIN释放请求,用来关闭主机B向主机A的数据传输,主机B进入LAST_ACK状态;

第四次挥手:主机A收到主机B的FIN请求,回送给主机BACK确认信息,四次挥手完毕

 

三、TCP特点:

全双工链接

该链接的两端有两条彼此独立、方向相反的传输通道,连接双方都需要建立TCP连接

面向连接

通信双方在开始传输数据前,必须通过“三次握手”的方式建立一条逻辑上的链路,用于传输数据

可靠协议

TCP协议借助于序列号和确认号,可以再数据包丢失的情况下进行重传,而通过确认号可以确定数据包是否没有收到是否是被重传的,依靠这些保证数据的可靠性

面向字节流

TCP协议会将数据包切分切分为很多小的数据包,并封装为ip包进行发送,被切分的数据包序列号不断变化,并不会按顺序到达, 根据接收方根据序列号和确认号进行重组

 

为什么连接的时候是三次握手,关闭的时候却是四次握手?

 

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

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

 

答:虽然按道理,四个报文都发送完毕,我们可以直接进入CLOSE状态了,但是我们必须假象网络是不可靠的,有可以最后一个ACK丢失。所以TIME_WAIT状态就是用来重发可能丢失的ACK报文。在Client发送出最后的ACK回复,但该ACK可能丢失。Server如果没有收到ACK,将不断重复发送FIN片段。所以Client不能立即关闭,它必须确认Server接收到了该ACK。Client会在发送出ACK之后进入到TIME_WAIT状态。Client会设置一个计时器,等待2MSL的时间。如果在该时间内再次收到FIN,那么Client会重发ACK并再次等待2MSL。所谓的2MSL是两倍的MSL(Maximum Segment Lifetime)。MSL指一个片段在网络中最大的存活时间,2MSL就是一个发送和一个回复所需的最大时间。如果直到2MSL,Client都没有再次收到FIN,那么Client推断ACK已经被成功接收,则结束TCP连接。

 

如果已经建立了连接,但是客户端突然出现故障了怎么办?

 

TCP还设有一个保活计时器,显然,客户端如果出现故障,服务器不能一直等下去,白白浪费资源。服务器每收到一次客户端的请求后都会重新复位这个计时器,时间通常是设置为2小时,若两小时还没有收到客户端的任何数据,服务器就会发送一个探测报文段,以后每隔75分钟发送一次。若一连发送10个探测报文仍然没反应,服务器就认为客户端出了故障,接着就关闭连接。

 

 

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值