TCP可靠在哪?

TCP可靠在哪?

    众所周知,TCP是一个面向连接的、基于流的、端到端的、可靠数据传输协议。那么,TCP究竟是如何确保数据传输的可靠性呢?

    注意:可靠传输不意味着数据安全,数据在传输中仍有被篡改数据并修改checksum的可能!

checksum

    checksum由发送方计算,接收方用其来检验数据是否完整。把伪首部(IP头部分)、TCP包头,TCP数据分为16位的字,如果总长度为奇数个字节,则在其最后补充一个值都为0的字节。在TCP报头中把校验和字段置为0,用反码相加法累加所有的字,最后取反作为TCP校验和。

    注意:checksum是不可逆的操作,所以,如果接收方验证checksum失败,则数据包一定不可靠,但是如果接收方验证checksum成功,数据包也不一定就是可靠的。

确认应答与序列号

    TCP协议将数据给每个字节都分配一个唯一的、递增的序列号(sequence number 16 bit),这个机制非常重要,接收方可以通过序列号进行去重,拒绝接受重复数据。确认应答机制是指接收方收到TCP包之后,会向发送方回传一个带有ACK标志位的TCP包,告诉发送方自己收到了哪些数据。

超时重传

    TCP每发送一部分数据之后都要接受ACK包以确认是否发送成功。那么在这个交互的过程中,如果发送方没有接收到ACK是否要一直阻塞下去呢?没有收到ACK包可能是在发送数据的过程中数据包丢失了,也有可能是在返回的过程中ACK包丢失了。这个时候TCP的超时重传机制发挥作用,在等待一个最大超时时间之后,TCP将重新发送刚才丢失的数据包,如果该数据包是因为第一个原因丢失的,则接收方重新接受,若成功就返回ACK,若数据包丢失的愿意是第二种,则接收方利用sequence number去重,丢掉该数据包,直接返回ACK。那具体要等待多长时间之后进行超时重传呢?一般来讲操作系统会有一个初始值,然后会以初始值的x次方作为最大超时时间,x表示当前重传次数。累计达到一定的重传次数,操作系统就会认为网络状况太差,强行中断连接。

连接管理

    通俗的讲,连接管理就是我们耳熟能详的三次握手和四次挥手。

TCP可靠在哪?_第1张图片

    相信这种讲TCP握手的图,大家没少见。这里就不细说了,主要讲为什么需要三次,第三次存在的必要。举个很简单的例子,如果女神给你发消息,国际标准,一句“在吗?”,你非常高兴,回她一句“我在!”。这个时候问题出现了,如果她就此不发消息,你是否会怀疑可能因为网络状况她根本就没收到你的回复。这就是问题的关键,第三次握手就是对确认的确认,让接收方也“心安”。

TCP可靠在哪?_第2张图片

    再来看四次挥手,同样具体步骤其实非常简单,那么为什么挥手需要四次呢?其实道理也非常简单,当服务器收到客户端的FIN之后,只能说明什么?说明客户端想走。但是服务器想不想让它走呢?这得取决于服务有没有完成,如果缓冲区中还有数据,那么要不要发呢?答案是肯定的。所以客户端是想走就走,可服务器做事稳重,需要考虑很多东西,等处理完善了,才想客户端发送FIN。完成挥手。

流量控制

    现实中网络受很多因素干扰,不同的网卡,不同的网络环境,都可能会影响到网速。而接收方与发送方之间带宽的不匹配是一个很大的问题,如果发送方带宽很大,接收方来不及收怎么办?这就引入了滑动窗口协议。接收方在接受完一个TCP包之后,所返回的ACK报文中会携带滑动窗口的大小,这个大小一般是接收方缓冲区的剩余大小。发送方发送数据包之前会先发一个窗口探测的包。根据对方窗口余量进行数据放松,做到双方带宽匹配。为了避免流量控制引发的死锁,TCP使用了持续计时器。每当发送者收到一个零窗口的应答后就启动该计时器。时间一到便主动发送报文询问接收者的窗口大小。若接收者仍然返回零窗口,则重置该计时器继续等待;若窗口不为0,则表示应答报文丢失了,此时重置发送窗口后开始发送,这样就避免了死锁的产生。

拥塞控制

    TCP为了在传输中避免网络拥堵,采取了一种试探的技术,以比较智能的方法规避拥堵,这就是拥塞控制的手段。在刚开始发送的时候将发送窗口定义为1,拥塞窗口为1意味着当前每发送1个包就需要收到应答,之后每收到一次ACK,就将这个值乘2,每超时重传一次就将这个值减半,这就是所谓的“慢开始”。拥塞控制还引入“快重传”的概念以提高吞吐量。快重传要求接收方在收到一个失序的报文段后就立即发出重复确认。快重传算法规定,发送方只要一连收到三个重复确认就应当立即重传对方尚未收到的报文,而不必继续等待设置的重传计时器时间到期。

你可能感兴趣的:(网络传输协议)