TCP和UDP,最新阿里+头条+腾讯大厂Java笔试真题

[](

)二、TCP

========================================================================

首先TCP是传输层的协议,特点是有连接,可靠传输,面向字节流

先了解TCP的报文结构

在这里插入图片描述

报文结构我们不需要全部了解,掌握重点的就可以了,

32位序号用来确保数据之间的先后顺序,

4位首部长度单位是4个字节,能表示的数据范围是0~15,如果是15,则表示TCP首部长度就是60个字节

TCP的六个标志位,每个标志位是1个bit 后面会介绍重要的几个

[](

)TCP的核心机制


[](

)2.1确认应答

确认应答机制是确保TCP可靠性的核心机制,

TPC将每一个字节的数据进行了编号,当主机A向主机B发送数据时,主机B回复一个确认收到的响应(ACK),当发送方收到应答数据时,如果应答报文的确认序号为1001,这时候发送方就知道了 1—1000的数据已经顺利抵达,并且接下来发送的数据就是从1001开始,但是可能会发生丢包情况,等待一点时间后,进行重传(超时重传),到一定限制后就不会进行重传了。

但是可能会发生一份数据多次发送的情况,TCP自身已经处理了这种情况,TCP中有一个“接收缓冲区”TCP就会通过序号检查是否重复。

TCP协议通过确认应答和超时重传的方式来确保数据TCP的可靠性

[](

)2.2超时重传

如果多次没有收到该数据包的响应,就会触发超时重传机制,重新将没有收到的响应发送一遍,如果还是没有收到响应就继续重发,并且等待时间成指数增长,可能第一次是500ms,下一次就是2 * 500ms,下一次就是2^2 * 500ms,到达一定的次数之后TCP就认为网络或者目的主机出问题,就强制进行关闭。

[](

)2.3连接管理

[](

)2.3.1三次握手

三次握手的本质就是确认通信双方的发送能力和接收能力都是正常的

在这里插入图片描述

第一次握手发送SYN(建立连接)主机B就知道自己的接收能力时正常的以及主机A的发送能力时正常的,

第二次握手,主机A收到SYN+ACK(确认应答)就知道主机B的发送能力是正常的,以及自己的接收能力是正常的,并且还有隐性条件就是主机A的发送能力是正常的,主机B的接收能力是正常的,通过第二次握手主机A就已经知道通信双方的接收和发送能力是正常的,但是主机B不确定

第三次握手,主机A向主机B发送应答响应,这时主机B收到后,就知道自己的发送能力以及主机A的接收能力时正常的,至此通信双方接收能力和发送能力都正常。

[](

)2.3.2为什么是三次握手,四次不行吗?两次?

首先四次握手就是将主机B的应答报文和建立连接报文分开,四次也能建立连接,但是没有必要,传输效率低了,

如果是两次呢? 不行,三次握手就是让通信双方确认接收能力和发送能力都正常,但是两次握手主机B不能确认自己的发送能力和主机A的接收能力是否正常,如果第一次发送SYN由于其他原因(网络延迟等)没有发送到主机B,等待了一定时间后,主机A重新发送了一个SYN,和主机B建立了连接,在传输数据中,第一次的SYN又经历种种困难,重新发送到主机B了,这时主机B就会以为建立了新的连接,造成了刚才的连接中断,数据丢失。

[](

)2.3.3四次挥手

通过四次挥手来断开连接

在这里插入图片描述

首先主机A向主机B发送结束报文段FIN,

中间的二次交互能不能和为一次?只能说有可能会,因为断开连接的时候主机B发送的ACK是操作系统内核的行为,就在收到FIN的第一时间就会回复,而发送FIN是应用程序的行为,在代码中执行到close()才会触发FIN,是合并的理由是如果close()很快就会被调用,那么就会触发延时回答和捎带应答,这样就把两个数据变为一条了,所有说四次挥手有可能是三次挥手,但是大概率是四次挥手,

TCP连接中一些核心的状态

E STABLISHED (稳定)连接建立成功

LISTEN 服务器端的状态,服务器准备就绪,允许客户端随时来建立连接

CLOSE_WAIT (四次挥手中) 等待关闭,出现在收到FIN ,返回ACK,到发送FIN这个时间间隙中,

在三次握手和四次挥手之间也会涉及到超时重传,和确认应答

TIME_WAIT 谁主动建立连接,谁有这个状态(注意建立连接是客户端实现的,而断开连接客户端和服务器都可以实现)为了防止最后一个ACK丢包做准备的,即进行最后一个ACK发送完毕后,不会立即销毁连接,而是以TIME_WAIT的状态等待一定时间,如果没有收到对方的FIN就认为ACK没有丢包,就真正释放连接,如果一定时间内对方重传了FIN就认为ACK丢了,就进行重传ACK TIME_WAIT 等待时间是2 MSL,MSL是表示网络中,两个主机传输数据的最大时间间隔

[](

)2.4 滑动窗口

通过前面的描述我们了解到每次发送数据时都是等待应答到了才会发送下一个数据,这样确保了可靠性,但是我们想在确保可靠性的条件下也能让效率更高,通过滑动窗口来实现提高效率。

滑动窗口就是我们通过连续发送一组数据,等待这一组的ACK,之后再发下一组的数据,这样就能做到节约时间了,这一组数据能发多少,这个数据量,就称为“窗口大小”,即窗口大小指的是无需确认等待而可以继续发送的数据最大值,发送窗口大小的数据,不需要等待ACK直接发送,收到第一个ACK后,窗口向后移动,类似于滑动窗口,操作系统的内核为了维护这个滑动窗口,需要开辟发送缓冲区来记录当前数据还有哪些没有被应答,只有确认应答后的数据才被发送缓冲区删掉,窗口越大,网络的吞吐率就越高,

问题:滑动窗口提高了效率但是如何保证可靠性,以及发生丢包情况怎么处理

ACK丢失,只要后续的收到了ACK就能知道前面数据传输效果怎么样,即丢失ACK后,序号确认机制就能弥补这样的错误,只要后续的序号到达之后,就能证明前的数据传输正常,即使ACK丢了也没关系。

数据包丢失,ACK确认序号就是再已经到达的序号基础上加1,如果中间的数据包丢失,ACK就会一直返回的响应序号为丢失前序号的下一个,如果1~1000序号数据包正常到达,1001 ~ 2000数据包丢失,即使后面发送了2001 ~ 3000的数据包,ACK也只会重复响应1001, 客户端这边收到了多次的1001序号,就知道1001 ~ 2000数据包丢失了,就只重传这部分的数据,所以不会重复重传数据。

重传机制得益于确认序号的加持,即保证了传输效率是比较高的,重传效率也是比较高的,因为没有重复的数据重传–快速重传

滑动窗口可靠性也有,效率也提高了,所以滑动窗口的大小,到底多少合适,窗口大了,效率提高了,但是内存消耗大

窗口太小,效率减少,但是内存占用少,还有接受方的处理速度也会影响窗口大小,所以我们就要对窗口大小进行限制,就是根据接受方的处理能力,来限制就引出了流量控制

[](

)2.5 流量控制

主机A向主机B发送数据,主机B返回的数据除了有ACK以外还有接收方缓冲区的空余大小,如果接受方缓冲区空余大小为等,主机A就会等待一定的时机,过了重发超时的时间以后,如果还没有收到窗口更新的消息,主机A救会发送一个窗口探测来确实当前接收方缓冲区剩余大小

流量控制的目的就是让发送方和接收方的速率尽可能一致,才能做到尽可能可靠并且高效,根据这个大小,发送发就能确定接下来的窗口大小为多少,所以窗口的大小是动态变化的,实际情况下,网络传输中取决于中间处理最慢的设备,还要考虑中间设备的处理能力,所以引出了拥塞控制

[](

)2.6 拥塞控制

滑动窗口的大小取决于拥塞控制和流量控制一起决定的,发送方,采用一个动态变化的过程,来试探出当前窗口大小多少合适,发送方在初始的情况下先设置一个比较小的窗口大小(慢开始),如果没有丢包就说明网络畅通就增大窗口大小,一直到出现丢包了就缩小窗口大小。

滑动窗口的大小就是拥塞控制和流量控制的较小值

所以TCP 并不适合效率要求特别高的场景,

[](

)2.7 延时应答

延时应答也是一个提高效率的方式,就是在应答ACK时,并不是立刻返回ACK而是等待一会(500ms),之后再返回ACK,这样可能,ACK携带的滑动窗口的大小可能更大了(接收缓冲区在等待的时间里处理了一些数据),这样传输的效率又会变得更大了。

所有的包适合延时应答吗?不是的,数量限制:每隔n个包就延时应答一次,时间限制:超过最大延时时间就应答一次,

[](

)2.8 捎带应答

当前我们最常见的服务器通信模式就是一问一答,在一问一答的情况下,我们需要四次TCP数据的交互,一问返回一个ACK,一答返回一个ACK,主要是返回ACK是操作系统的内核实现的,接收到立刻返回ACK,而产生回答是代码响应的,按理说二者是有时间的间隔,但是TCP中有延时应答,所以理论上二者有可能同一时间应答,所以说捎带应答就是建立在延时应答的基础上

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值