【计算机网络专题】TCP相关问题(必看题)
本问题对应的项目链接:高频题回答模版训练
PS:TCP也是重灾区,理解越深越好,一般部分面试官才回问的比较深
1、什么是 TCP ?举几个应用了 TCP 协议的例子
2、TCP协议如何保证可靠性?
3、tcp如何保证不会接受重复的报文?
4、Tcp粘包拆包问题了解吗?介绍一下,如何解决?
5、TCP拥塞控制与流量控制区别?
6、现在我们视频面试用到哪些协议?
本问题对应的项目链接:高频题回答模版训练
PS:TCP也是重灾区,理解越深越好,一般部分面试官才回问的比较深
1、什么是 TCP ?举几个应用了 TCP 协议的例子
2、TCP协议如何保证可靠性?
3、tcp如何保证不会接受重复的报文?
4、Tcp粘包拆包问题了解吗?介绍一下,如何解决?
5、TCP拥塞控制与流量控制区别?
6、现在我们视频面试用到哪些协议?
共以下 3 个回答
3、TCP如何保证不会接受重复的报文?
TCP中发送报文前都会加上自己的初始化序列号,在接收方接收到消息后一半会将发送方的序列号+1作为ACK回发给发送方,从而告诉发送方已经收到了该条报文。如果接收方收到重复序列号的报文则直接丢弃。
1、什么是 TCP ?举几个应用了 TCP 协议的例子
TCP全称是传输控制协议,它是面向连接的,可靠的,字节流传输协议。面向连接指的是主机之间逻辑上的连接,通信双方通过维护发送窗口,接收窗口等一系列属性/资源来保持一个逻辑连接,并且通过三次握手交换序列号,以及通过超时重传/快速重传等手段来保证报文段,有序的无冗余的无重复的从发送方交付到接受方,面向字节流指的是TCP会将上层交付下来的一个报文分成多个TCP报文段,并以字节为单位标出序号,所以我们不能保证一个TCP报文段就是一个完整的数据报。
2、TCP协议如何保证可靠性?
首先会通过三次握手,交换对方发送出来数据的初始字节序号。在通信过程中发送方会在TCP报文段首部记录当前数据流的首个字节的序号,接受方每收到一个/多个报文段都会对已收到的字节序号进行确认记录在TCP首部的确认序号中,表示在该序号之前的数据我已经全部完整接受,请发送该序号及以后的数据。如果因为网络丢包或者拥塞导致数据无法正确交付或无法收到对该报文段的ack,就会触发超时重传,重新发送未被确认的报文段。还有一种以数据驱动的重传方式快速重传,当发送方收到对同一个报文段的ack三次后,就会触发快速重传但是发送方并不知道需要重传一个报文段还是重传这之后的哪些。所以出现了sack选择性重传,确认方通过sack字段来告知发送方哪段序列已经被正确接受,只需要重传缺失的那段就好了。
3、tcp如何保证不会接受重复的报文?
接收方维护着一个接收窗口,通过TCP首部的序列号和该报文段的长度来识别该报文段是否在接收窗口内,并且接收窗口是否已经存在该报文段,如果存在就丢弃。重复报文的接收可能是因为接收方的ack报文在网络中拥塞或丢失造成的,发送方通过超时重传机制不断发送相同的报文段,但接收方可以通过sack字段来告知发送方哪些报文段是重复发送的,这样就减少了发送方不断超时重传的代价。
4、Tcp粘包拆包问题了解吗?介绍一下,如何解决?
TCP粘包主要是因为TCP是面向字节流的协议,他会将上层的数据报拆分成多个报文段,就会导致接受方收到的一系列报文段可能不属于同一个数据报的。
解决粘包可以通过特殊字符作为边界,读到指定的特殊字符就认定为是一个数据报HTTP就通过回车和换行来作为报文的边界。
还可以通过自定义消息结构,分为消息头和消息体,在消息头中声明该消息体的长度大小,其中消息头的长度是固定的
5、TCP拥塞控制与流量控制区别?
拥塞控制是通过是否发生了超时重传或者快速重传感知网络的拥塞程度,进而控制发送方的拥塞/发送窗口,调整发送速率让网络不那么拥挤的同时快速的发送数据。
具体来说首先在刚经历三次握手建立TCP连接后会有一个慢启动的过程,首先会将拥塞窗口初始化为1MSS,在这之后每接受到一个ack就会使拥塞窗口+1MSS,这一过程是指数增长的,当拥塞窗口达到慢启动的阈值时就会进入拥塞避免阶段。拥塞避免阶段每收到一个ack就会拥塞窗口就会增加1/cwnd,这一过程是线性增长的,假如拥塞窗口大小为8,我收到了8个ack那拥塞窗口就会增加1MSS。如果在这一过程中发生了超时重传,那就会将慢启动的阈值设为cwnd/2,并将拥塞窗口置为1重新进入慢启动的状态。如果此时连续收到3个冗余ack发生了快速重传,此时代表网络并不像超时重传那样拥塞,就会将慢启动阈值设为cwnd/2,将cwnd设为慢启动阈值,进入快速恢复阶段,先把cwnd+3含义就是我收到了3次冗余ack目的是尽快的将丢失的数据发送出去,如果再收到冗余ack还会把cwnd+1,如果收到了新的ack代表丢失的数据已经弥补了,重新将cwnd设为慢启动阈值进入拥塞避免状态。
流量控制是接受方通过TCP首部的窗口大小字段来告知发送方自己的接受能力,防止发送方速率过快,而导致接受方接受缓冲区溢出,无法处理发来的数据。
发送方的发送窗口通过记录已发送但还未被ack的报文段以及准备发送到网络中的报文段来进行流量控制,如果接收方的接受窗口减小,发送方也会对应的调整自己的发送窗口,使其保持一致
6、现在我们视频面试用到哪些协议?
1、什么是 TCP ?举几个应用了 TCP 协议的例子
TCP 是面向连接的,可靠的,基于字节流的传输层通信协议。其中面向连接一定是一对一的连接。可靠性是指无论网络链路中出现了什么状况,TCP 都可以保证一个报文能够无损坏,无冗余,按序到达。基于字节流是指用户消息通过 TCP 协议传输时,会被操作系统分组成多个 TCP 报文,并且这些报文之间是有序的。
像我们平时用到的最多的网页中的 HTTP 协议,传输层协议就是 TCP。类似用到 TCP 的应用层还有 FTP 文件传输协议,SMTP 简单邮件传输协议和 SSH,它们的传输层都需要 TCP 来做可靠性保证。
2、TCP协议如何保证可靠性?
首先 TCP 每次建立连接都需要三次握手,释放连接需要四次挥手来确保建立的传输通道是可靠的。
其次,TCP 采用了连续 ARQ 协议来保证数据传输的正确性,同时还使用了滑动窗口机制来控制发送方的发送速率,保证接收方一定能接受到发送的数据,也就是流量控制机制。
还有,TCP 利用序列号和校验和,来分别确保数据传输的有序性和完整性。
最后在整个网络层面上,TCP 还使用慢开始,拥塞避免,快速重传和快速回复来进行拥塞控制,避免网络阻塞带来的数据接收问题。
3、tcp如何保证不会接受重复的报文?
这个是由 TCP 报文中的“序列号”字段保证的,TCP 在建立连接时,客户端和服务端都会将一个内核生成的随机数作为自己的初始序列号。在建立连接完成后,开始发送数据时,发送的一端会将“上次发送的序列号”加上“上次发送的数据长度”作为“本次报文的序列号”发送给对端。对端在收到数据包时,会根据序列号来确定接收到数据的顺序和是否重复,如果重复收到某个序列号的报文,则只会接收一次,其他的都丢弃。
需要注意的是,在三次握手和四次挥手阶段,发送端序列号的值就不是“上次发送的序列号”加上“上次发送的数据长度”的值,而是“上次发送的序列号”加上 “1”。
还有,序列号除了确保数据接收的“有序性”,还有用于 TCP 的流量控制中。具体的,TCP 连接的两端都会维护一个发送窗口和接受窗口。发送方根据 TCP 报文的序列号和发送窗口的大小来确定可以发送的数据量。接收方使用序列号和接收窗口大小来确定可以接收的数据量,并通知发送方来控制发送速率,以此来确保双方数据都能够被顺利接收。
4、Tcp粘包拆包问题了解吗?介绍一下,如何解决?
首先 TCP 是处在传输层的面向流的协议的协议,它本身不会按照应用开发者的期望,保持每次发送时都带有一个数据的边界,这可能导致接收端一次收到了多个应用层报文,需要应用开发者自己分开,也就是需要自己去实现“流”到“数据报”的功能。具体的解决,可以用“特殊字符作为边界”,也就是我们对于应用层的每个信息后面都加上一些特殊字符用来代表信息结束。当读到了这些特殊字符,就意味着已经读完了一个完整的消息。比如 HTTP 通过设置回车符和一个换行符来作为 HTTP 报文协议的边界。但需要注意的是,如果信息内容中刚好出现了这些字符,可能会导致信息提前结束和数据错乱,这时我们可以对这些个字符进行转义,避免这种情况。
其实还有一种“粘包”的含义:就是 TCP 在实现的时候,为了解决大量小报文场景下,包头比数据还大,导致传输的性价比太低的情况,采用了一种叫 Nagle 的算法。这个算法的效果就是将开发者多次发送的小数据,粘在同一个 TCP 报文中发出。这样可能就会导致先被发送的数据可能需要等待一段时间,才能跟后面才被发送的数据一起组成报文发送出去。但在实际中这种算法带来的延迟几乎可以忽略不计,绝大多数情况都是无感知的。只有在频繁进行超短信息的交互,比如只有几个字节的场景,禁用 Nagle 算法才能显著降低延迟。
5、TCP拥塞控制与流量控制区别?
两者诞生的原因就不同:
需要流量控制的原因是,端到端在通信时,发送方的速率与接收方的速率不一致,如果发送方发的速率太快,会导致接收方处理不过来;而如果发送方发送的太慢,数据就会有一定的延迟。那么此时就需要通过一种方法来控制发送方的速率,这个方法就叫“流量控制”
而拥塞控制不同于流量控制,它主要强调的是网络的拥塞,导致发送方发的数据包被堵在了半路,而接收方迟迟没收到数据包并返回接收到的最后一个包的确认报文,会让发送方误以为这个包丢了并重新发送,这不仅会浪费信道资源,还会使原来拥塞的网络雪上加霜。
6、现在我们视频面试用到哪些协议?
考虑到视频时对于延迟很敏感,所以应该具有 UDP 传输速度快的特性,但又能允许一定程度的丢包。但又不能丢包率太高,还应具备 TCP 有关数据传输可靠性的保证,确保不会视频着视频着突然画面就没有了的情况。所以我觉得应该是同时结合了 TCP 可靠性和 UDP 速度快的优点,这类协议我了解的是谷歌提出的 QUIC 协议。
QUIC 协议全称是“快速 UDP 互联网”连接,相比与当前应用多的 http2 + tcp + tls,它的优势主要在减少了 TCP 三次握手以及 TLS 握手的时间,拥有改进后的拥塞控制,以及拥有避免队头阻塞的多路复用。
首先由于 UDP 本身没有连接的概念,不需要三次握手,QUIC 在此基础上实现了 0 RTT 的安全握手,并且在大部分情况下也只需 0 RTT 就能实现数据发送。
为了保证可靠性传输,QUIC 在 TCP 关于拥塞控制方面的四个算法,包括慢启动,拥塞避免,快速重传,快速回复都做了相应的改进。比较突出的特点就是,QUIC 使用 packet number 代替了 TCP 的 sequence number,且每个 packet number 都严格递增。加上同样是 QUIC 提出的 Stream Offset,确保数据的顺序性和可靠性。
除此之外,QUIC 还在 Connection 和 Stream 两个级别都提供了流量控制。Stream 可以理解为一条 http 请求,Connection 可以类比一条 TCP 连接。QUIC 的多路复用就是指在一条 Connection 上同时存在多条 Stream,且多条 Stream 之间没有顺序依赖,也就消除了 TCP 中队头阻塞的问题。
大致只了解这么多。