文章目录
- 17、说说 TCP 可靠性保证?
- 18、简述 TCP 滑动窗口以及重传机制?
- 19、说说滑动窗口过小怎么办?
- 20、说说如果三次握手时候每次握手信息对方没收到会怎么样,分情况介绍?
- 21、简述 TCP 的 TIME_WAIT,为什么需要有这个状态?
- 22、简述什么是 MSL,为什么客户端连接要等待2MSL的时间才能完全关闭?
- 23、说说什么是 SYN flood,如何防止这类攻击?
- 24、 说说什么是 TCP 粘包和拆包?
- 25、说说 TCP 与 UDP 在网络协议中的哪一层,他们之间有什么区别?
- 26、说说从系统层面上,UDP 如何保证尽量可靠?
- 27、说一说 TCP 的 keepalive,以及和 HTTP 的 keepalive 的区别?
- 28、简述 TCP 协议的延迟 ACK 和累计应答?
- 29、说说 TCP 如何加速一个大文件的传输?
- 30、服务器怎么判断客户端断开了连接?
- 31、说说端到端,点到点的区别?
- 32、说说浏览器从输入 URL 到展现页面的全过程?
17、说说 TCP 可靠性保证?
TCP主要提供了检验和、序列号/确认应答、超时重传、最大消息长度、滑动窗口控制等方法实现了可靠性传输。
1.检验和:
通过检验和的方式,接收端可以检测出来数据是否有差错和异常,假如有差错就会直接丢弃TCP段,重新发送。TCP在计算检验和时,会在TCP首部加上一个12字节的伪首部。检验和总共计算3部分:TCP首部、TCP数据、TCP伪首部
2.序列号/确认应答:
这个机制类似于问答的形式。比如在课堂上老师会问你“明白了吗?”,假如你没有隔一段时间没有回应或者你说不明白,那么老师就会重新讲一遍。其实计算机的确认应答机制也是一样的,发送端发送信息给接收端,接收端会回应一个包,这个包就是应答包。上述过程中,只要发送端有一个包传输,接收端没有回应确认包(ACK包),都会重发。或者接收端的应答包,发送端没有收到也会重发数据。这就可以保证数据的完整性!
3.超时重传:
超时重传是指发送出去的数据包到接收到确认包之间的时间,如果超过了这个时间会被认为是丢包了,需要重传。那么我们该如何确认这个时间值呢?
我们知道,一来一回的时间总是差不多的,都会有一个类似于平均值的概念。比如发送一个包到接收端收到这个包一共是0.5s,然后接收端回发一个确认包给发送端也要0.5s,这样的两个时间就是RTT(往返时间)。然后可能由于网络原因的问题,时间会有偏差,称为抖动(方差)。从上面的介绍来看,超时重传的时间大概是比往返时间+抖动值还要稍大的时间。
但是在重发的过程中,假如一个包经过多次的重发也没有收到对端的确认包,那么就会认为接收端异常,强制关闭连接。并且通知应用通信异常强行终止!
4.最大消息长度:
在建立TCP连接的时候,双方约定一个最大的长度(MSS)作为发送的单位,重传的时候也是以这个单位来进行重传。理想的情况下是该长度的数据刚好不被网络层分块。
5.滑动窗口控制:
我们上面提到的超时重传的机制存在效率低下的问题,发送一个包到发送下一个包要经过一段时间才可以。所以我们就想着能不能不用等待确认包就发送下一个数据包呢?这就提出了一个滑动窗口的概念。
窗口的大小就是在无需等待确认包的情况下,发送端还能发送的最大数据量。这个机制的实现就是使用了大量的缓冲区,通过对多个段进行确认应答的功能。通过下一次的确认包可以判断接收端是否已经接收到了数据,如果已经接收了就从缓冲区里面删除数据。
在窗口之外的数据就是还未发送的和对端已经收到的数据。那么发送端是怎么样判断接收端有没有接收到数据呢?或者怎么知道需要重发的数据有哪些呢?通过下面这个图就知道了。
如上图,接收端在没有收到自己所期望的序列号数据之前,会对之前的数据进行重复确认。发送端在收到某个应答包之后,又连续3次收到同样的应答包,则数据已经丢失了,需要重发。
6.拥塞控制:
- 窗口控制解决了 两台主机之间因传送速率而可能引起的丢包问题,在一方面保证了TCP数据传送的可靠性。然而如果网络非常拥堵,此时再发送数据就会加重网络负担,那么发送的数据段很可能超过了最大生存时间也没有到达接收方,就会产生丢包问题。为此TCP引入慢启动机制,先发出少量数据,就像探路一样,先摸清当前的网络拥堵状态后,再决定按照多大的速度传送数据。
- 发送开始时定义拥塞窗口大小为1;每次收到一个ACK应答,拥塞窗口加1;而在每次发送数据时,发送窗口取拥塞窗口与接送段接收窗口最小者。
- 慢启动:在启动初期以指数增长方式增长;设置一个慢启动的阈值,当以指数增长达到阈值时就停止指数增长,按照线性增长方式增加至拥塞窗口;线性增长达到网络拥塞时立即把拥塞窗口置回1,进行新一轮的“慢启动”,同时新一轮的阈值变为原来的一半。
18、简述 TCP 滑动窗口以及重传机制?
- 滑动窗口协议是传输层进行流控的一种措施,接收方通过通告发送方自己的窗口大小,从而控制发送方的发送速度,从而达到防止发送方发送速度过快而导致自己被淹没的目的。TCP的滑动窗口解决了端到端的流量控制问题,允许接受方对传输进行限制,直到它拥有足够的缓冲空间来容纳更多的数据。
- TCP在发送数据时会设置一个计时器,若到计时器超时仍未收到数据确认信息,则会引发相应的超时或基于计时器的重传操作,计时器超时称为重传超时(RTO) 。另一种方式的重传称为快速重传,通常发生在没有延时的情况下。若TCP累积确认无法返回新的ACK,或者当ACK包含的选择确认信息(SACK)表明出现失序报文时,快速重传会推断出现丢包,需要重传。
19、说说滑动窗口过小怎么办?
- 我们可以假设窗口的大小是1,也是就每次只能发送一个数据,并且发送方只有接受方对这个数据进行确认了以后才能发送下一个数据。如果说窗口过小,那么当传输比较大的数据的时候需要不停的对数据进行确认,这个时候就会造成很大的延迟。
20、说说如果三次握手时候每次握手信息对方没收到会怎么样,分情况介绍?
- 如果第一次握手消息丢失,那么请求方不会得到ack消息,超时后进行重传
- 如果第二次握手消息丢失,那么请求方不会得到ack消息,超时后进行重传
- 如果第三次握手消息丢失,那么Server 端该TCP连接的状态为SYN_RECV,并且会根据 TCP的超时重传机制,会等待3秒、6秒、12秒后重新发送SYN+ACK包,以便Client重新发送ACK包。而Server重发SYN+ACK包的次数,可以设置/proc/sys/net/ipv4/tcp_synack_retries修改,默认值为5.如果重发指定次数之后,仍然未收到 client 的ACK应答,那么一段时间后,Server自动关闭这个连接。client 一般是通过 connect() 函数来连接服务器的,而connect()是在 TCP的三次握手的第二次握手完成后就成功返回值。也就是说 client 在接收到 SYN+ACK包,它的TCP连接状态就为 established已连接),表示该连接已经建立。那么如果 第三次握手中的ACK包丢失的情况下,Client 向server端发送数据,Server端将以 RST包响应,方能感知到Server的错误。
21、简述 TCP 的 TIME_WAIT,为什么需要有这个状态?
- TIME_WAIT状态也称为2MSL等待状态。每个具体TCP实现必须选择一个报文段最大生存时间MSL(Maximum Segment Lifetime),它是任何报文段被丢弃前在网络内的最长时间。这个时间是有限的,因为TCP报文段以IP数据报在网络内传输,而IP数据报则有限制其生存时间的TTL字段。对一个具体实现所给定的MSL值,处理的原则是:当TCP执行一个主动关闭,并发回最后一个ACK,该连接必须在TIME_WAIT状态停留的时间为2倍的MSL。这样可让TCP再次发送最后的ACK以防这个ACK丢失(另一端超时并重发最后的FIN)。这种2MSL等待的另一个结果是这个TCP连接在2MSL等待期间,定义这个连接的插口(客户的IP地址和端口号,服务器的IP地址和端口号)不能再被使用。这个连接只能在2MSL结束后才能再被使用。
- 理论上,四个报文都发送完毕,就可以直接进入CLOSE状态了,但是可能网络是不可靠的,有可能
最后一个ACK丢失。所以TIME_WAIT状态就是用来重发可能丢失的ACK报文。
22、简述什么是 MSL,为什么客户端连接要等待2MSL的时间才能完全关闭?
- MSL是Maximum Segment Lifetime的英文缩写,可译为“最长报文段寿命”,它是任何报文在网络
上存在的最长时间,超过这个时间报文将被丢弃。 - 为了保证客户端发送的最后一个ACK报文段能够到达服务器。因为这个ACK有可能丢失,从而导致处在LAST-ACK状态的服务器收不到对FIN-ACK的确认报文。服务器会超时重传这个FIN-ACK,接着客户端再重传一次确认,重新启动时间等待计时器。最后客户端和服务器都能正常的关闭。假设客户端不等待2MSL,而是在发送完ACK之后直接释放关闭,一但这个ACK丢失的话,服务器就无法正常的进入关闭连接状态。
两个理由:
- 保证客户端发送的最后一个ACK报文段能够到达服务端。
这个ACK报文段有可能丢失,使得处于LAST-ACK状态的B收不到对已发送的FIN+ACK报文段的确认,服务端超时重传FIN+ACK报文段,而客户端能在2MSL时间内收到这个重传的FIN+ACK报文段,接着客户端重传一次确认,重新启动2MSL计时器,最后客户端和服务端都进入到CLOSED状态,若客户端在TIME-WAIT状态不等待一段时间,而是发送完ACK报文段后立即释放连接,则无法收到服务端重传的FIN+ACK报文段,所以不会再发送一次确认报文段,则服务端无法正常进入到CLOSED状态。 - 防止“已失效的连接请求报文段”出现在本连接中。
客户端在发送完最后一个ACK报文段后,再经过2MSL,就可以使本连接持续的时间内所产生的所有报文段都从网络中消失,使下一个新的连接中不会出现这种旧的连接请求报文段。
23、说说什么是 SYN flood,如何防止这类攻击?
- SYN Flood是当前最流行的DoS(拒绝服务攻击)与DDoS(分布式拒绝服务攻击)的方式之一,这是
一种利用TCP协议缺陷,发送大量伪造的TCP连接请求,使被攻击方资源耗尽(CPU满负荷或内存
不足)的攻击方式. - 有以下三种方法预防或响应网络上的DDoS攻击:
(1)从互联网服务提供商(ISP)购买服务。
许多互联网服务提供商(ISP)提供DDoS缓解服务,但是当企业网络受到攻击时,企业需要向互联网
服务提供商(ISP)报告事件以开始缓解。这种策略称为“清洁管道”,在互联网服务提供商(ISP)收取服
务费用时很受欢迎,但在缓解措施开始之前,通常会导致30到60分钟的网络延迟。
(2)保留在内部并自己解决。
企业可以使用入侵防御系统/防火墙技术和专用于防御DDoS攻击的专用硬件来实现内部预防和响应
DDoS攻击。不幸的是,受影响的流量已经在网络上消耗了宝贵的带宽。这使得该方法最适合在托
管设施中配备设备的企业,在这些企业中,流量是通过交叉连接到达互联网服务提供商(ISP),从而
保护流向企业其他部门的下游带宽。
(3)使用内容分发网络(CDN)。
由于IT团队可以将基础设施置于内容分发网络(CDN)后面,因此这种方法可以最大程度地减少对企
业网络基础设施的攻击。这些网络庞大而多样,如果组织订阅DNS和DDoS缓解措施,则它们可以
保护电子商务站点以及企业本身。
24、 说说什么是 TCP 粘包和拆包?
- TCP是个“流”协议,所谓流,就是没有界限的一串数据。大家可以想想河里的流水,是连成一片
的,其间并没有分界线。TCP底层并不了解上层业务数据的具体含义,它会根据TCP缓冲区的实际
情况进行包的划分,所以在业务上认为,一个完整的包可能会被TCP拆分成多个包进行发送,也有
可能把多个小的包封装成一个大的数据包发送,这就是所谓的TCP粘包和拆包问题。
- 假设客户端分别发送了两个数据包D1和D2给服务端,由于服务端一次读取到的字节数是不确定的,故可
能存在以下4种情况。
(1)服务端分两次读取到了两个独立的数据包,分别是D1和D2,没有粘包和拆包;
(2)服务端一次接收到了两个数据包,D1和D2粘合在一起,被称为TCP粘包;
(3)服务端分两次读取到了两个数据包,第一次读取到了完整的D1包和D2包的部分内容,第二次读取
到了D2包的剩余内容,这被称为TCP拆包;
(4)服务端分两次读取到了两个数据包,第一次读取到了D1包的部分内容D1_1,第二次读取到了D1包
的剩余内容D1_2和D2包的整包。如果此时服务端TCP接收滑窗非常小,而数据包D1和D2比较大,很有可能会发生第五种可能,即服务端分多次才能将D1和D2包接收完全,期间发生多次拆包。
25、说说 TCP 与 UDP 在网络协议中的哪一层,他们之间有什么区别?
TCP和UDP协议都是传输层协议。二者的区别主要有:
- 基于连接vs无连接
TCP是面向连接的协议。
UDP是无连接的协议。UDP更加适合消息的多播发布,从单个点向多个点传输消息。
- 可靠性
TCP提供交付保证,传输过程中丢失,将会重发。
UDP是不可靠的,不提供任何交付保证。(网游和视频的丢包情况) - 有序性
TCP保证了消息的有序性,即使到达客户端顺序不同,TCP也会排序。
UDP不提供有序性保证。 - 数据边界
TCP不保存数据边界。
虽然TCP也将在收集所有字节之后生成一个完整的消息,但是这些信息在传给传输给接受端之
前将储存在TCP缓冲区,以确保更好的使用网络带宽。
UDP保证。
在UDP中,数据包单独发送的,只有当他们到达时,才会再次集成。包有明确的界限来哪些
包已经收到,这意味着在消息发送后,在接收器接口将会有一个读操作,来生成一个完整的消
息。
- 速度
TCP速度慢
UDP速度快。应用在在线视频媒体,电视广播和多人在线游戏。 - 发送消耗
TCP是重量级。
UDP是轻量级。
因为UDP传输的信息中不承担任何间接创造连接,保证交货或秩序的的信息。
这也反映在用于报头大小。 - 报头大小
TCP头大。
一个TCP数据包报头的大小是20字节。
TCP报头中包含序列号,ACK号,数据偏移量,保留,控制位,窗口,紧急指针,可选项,填充项,校验位,源端口和目的端口。
UDP头小。
UDP数据报报头是8个字节。
而UDP报头只包含长度,源端口号,目的端口,和校验和。 - 拥塞或流控制
TCP有流量控制。
在任何用户数据可以被发送之前,TCP需要三数据包来设置一个套接字连接。TCP处理的可靠
性和拥塞控制。
UDP不能进行流量控制。 - 应用
由于TCP提供可靠交付和有序性的保证,它是最适合需要高可靠并且对传输时间要求不高的应用。
UDP是更适合的应用程序需要快速,高效的传输的应用,如游戏。
UDP是无状态的性质,在服务器端需要对大量客户端产生的少量请求进行应答的应用中是非常有用
的。
在实践中,TCP被用于金融领域,如FIX协议是一种基于TCP的协议,而UDP是大量使用在游戏和娱
乐场所。 - 上层使用的协议
基于TCP协议的:Telnet,FTP以及SMTP协议。
基于UDP协议的:DHCP、DNS、SNMP、TFTP、BOOTP。
26、说说从系统层面上,UDP 如何保证尽量可靠?
- UDP仅提供了最基本的数据传输功能,至于传输时连接的建立和断开、传输可靠性的保证这些UDP
统统不关心,而是把这些问题抛给了UDP上层的应用层程序去处理,自己仅提供传输层协议的最基
本功能。 - 最简单的方式是在应用层模仿传输层TCP的可靠性传输。下面不考虑拥塞处理,可靠UDP的简单设
计。
- 添加seq/ack机制,确保数据发送到对端
- 添加发送和接收缓冲区,主要是用户超时重传。
- 添加超时重传机制。
27、说一说 TCP 的 keepalive,以及和 HTTP 的 keepalive 的区别?
- HTTP Keep-Alive
在http早期,每个http请求都要求打开一个tpc socket连接,并且使用一次之后就断开这个tcp连接。使用keepalive可以改善这种状态,即在一次TCP连接中可以持续发送多份数据而不会断开连接。通过使用keep-alive机制,可以减少tcp连接建立次数,也意味着可以减少TIME_WAIT状态连接,以此提高性能和提高httpd服务器的吞吐率(更少的tcp连接意味着更少的系统内核调用,socket的accept()和close()调用)。但是,keep-alive并不是免费的午餐,长时间的tcp连接容易导致系统资源无效占用。配置不当的keep-alive,有时比重复利用连接带来的损失还更大。所以,正确地设置keep-alive timeout时间非常重要。 - TCP KEEPALIVE
链接建立之后,如果应用程序或者上层协议一直不发送数据,或者隔很长时间才发送一次数据,当链接很久没有数据报文传输时如何去确定对方还在线,到底是掉线了还是确实没有数据传输,链接还需不需要保持,这种情况在TCP协议设计中是需要考虑到的。TCP协议通过一种巧妙的方式去解决这个问题,当超过一段时间之后,TCP自动发送一个数据为空的报文给对方,如果对方回应了这个报文,说明对方还在线,链接可以继续保持,如果对方没有报文返回,并且重试了多次之后则认为链接丢失,没有必要保持链接! - TCP的keepalive机制和HTTP的keep-alive机制是说的完全不同的两个东西,tcp的keepalive是在ESTABLISH状态的时候,双方如何检测连接的可用行。而http的keep-alive说的是如何避免进行重
复的TCP三次握手和四次挥手的环节。
28、简述 TCP 协议的延迟 ACK 和累计应答?
- 延迟应答指的是:TCP在接收到对端的报文后,并不会立即发送ack,而是等待一段时间发送ack,
以便将ack和要发送的数据一块发送。当然ack不能无限延长,否则对端会认为包超时而造成报文重
传。linux采用动态调节算法来确定延时的时间。 - 累计应答指的是:为了保证顺序性,每一个包都有一个ID(序号),在建立连接的时候,会商定起
始的ID是多少,然后按照ID一个个发送。而为了保证不丢包,对应发送的包都要进行应答,但不是
一个个应答,而是会应答某个之前的ID,该模式称为累计应答!
29、说说 TCP 如何加速一个大文件的传输?
- 建连优化:TCP 在建立连接时,如果丢包,会进入重试,重试时间是 1s、2s、4s、8s 的指数递增
间隔,缩短定时器可以让 TCP 在丢包环境建连时间更快,非常适用于高并发短连接的业务场景。 - 平滑发包:在 RTT 内均匀发包,规避微分时间内的流量突发,尽量避免瞬间拥塞
- 丢包预判:有些网络的丢包是有规律性的,例如每隔一段时间出现一次丢包,例如每次丢包都连续
丢几个等,如果程序能自动发现这个规律(有些不明显),就可以针对性提前多发数据,减少重传
时间、提高有效发包率。 - RTO 探测:若始终收不到 ACK 报文,则需要触发 RTO 定时器。RTO 定时器一般都时间非常长,会
浪费很多等待时间,而且一旦 RTO,CWND 就会骤降(标准 TCP),因此利用 Probe 提前与 RTO
去试探,可以规避由于 ACK 报文丢失而导致的速度下降问题。 - 带宽评估:通过单位时间内收到的 ACK 或 SACK 信息可以得知客户端有效接收速率,通过这个速
率可以更合理的控制发包速度。 - 带宽争抢:有些场景(例如合租)是大家互相挤占带宽的,假如你和室友各 1Mbps 的速度看电
影,会把 2Mbps 出口占满,而如果一共有 3 个人看,则每人只能分到 1/3。若此时你的流量流量
达到 2Mbps,而他俩还都是 1Mbps,则你至少仍可以分到 2/(2+1+1) * 2Mbps = 1Mbps 的 50%
的带宽,甚至更多,代价就是服务器侧的出口流量加大,增加成本。(TCP 优化的本质就是用带宽
换用户体验感)
30、服务器怎么判断客户端断开了连接?
- 检测连接是否丢失的方法大致有两种:keepalive和heart-beat
- (tcp内部机制)采用keepalive,它会先要求此连接一定时间没有活动(一般是几个小时),然后
发出数据段,经过多次尝试后(每次尝试之间也有时间间隔),如果仍没有响应,则判断连接中
断。可想而知,整个周期需要很长的时间。 - (应用层实现)一个简单的heart-beat实现一般测试连接是否中断采用的时间间隔都比较短,可以
很快的决定连接是否中断。并且,由于是在应用层实现,因为可以自行决定当判断连接中断后应该
采取的行为,而keepalive在判断连接失败后只会将连接丢弃。
31、说说端到端,点到点的区别?
- 端到端通信是针对传输层来说的,传输层为网络中的主机提供端到端的通信。因为无论tcp还是udp协议,都要负责把上层交付的数据从发送端传输到接收端,不论其中间跨越多少节点。只不过tcp比较可靠而udp不可靠而已。所以称之为端到端,也就是从发送端到接收端。它是一个网络连接,指的是在数据传输之前,在发送端与接收端之间(忽略中间有多少设备)为数据的传输建立一条链路,链路建立以后,发送端就可以发送数据,知道数据发送完毕,接收端确认接收成功。 也就是说在数据传输之前,先为数据的传输开辟一条通道,然后在进行传输。从发送端发出数据到接收端接收完毕,结束。端到端通信建立在点到点通信的基础之上,它是由一段段的点到点通信信道构成的,是比点到点通信更高一级的通信方式,完成应用程序(进程)之间的通信。
端到端的优点:
链路建立之后,发送端知道接收端一定能收到,而且经过中间交换设备时不需要进行存储转发,因此传输延迟小。
端到端传输的缺点:
(1)直到接收端收到数据为止,发送端的设备一直要参与传输。如果整个传输的延迟很长,那么对发送端的设备造成很大的浪费。
(2)如果接收设备关机或故障,那么端到端传输不可能实现 - 点到点通信是针对数据链路层或网络层来说的,因为数据链路层只负责直接相连的两个节点之间的通信,一个节点的数据链路层接受ip层数据并封装之后,就把数据帧从链路上发送到与其相邻的下一个节点。 点对点是基于MAC地址和或者IP地址,是指一个设备发数据给与该这边直接连接的其他设备,这台设备又在合适的时候将数据传递给与它相连的下一个设备,通过一台一台直接相连的设备把数据传递到接收端。直接相连的节点对等实体的通信叫点到点通信。它只提供一台机器到另一台机器之间的通信,不会涉及到程序或进程的概念。同时点到点通信并不能保证数据传输的可靠性,也不能说明源主机与目的主机之间是哪两个进程在通信。由物理层、数据链路层和网络层组成的通信子网为网络环境中的主机提供点到点的服务
点到点的优点:
(1)发送端设备送出数据后,它的任务已经完成,不需要参与整个传输过程,这样不会浪费发送
端设备的资源。
(2)即使接收端设备关机或故障,点到点传输也可以采用存储转发技术进行缓冲。
点到点的缺点:
点到点传输的缺点是发送端发出数据后,不知道接收端能否收到或何时能收到数据。在一个网络系统的不同分层中,可能用到端到端传输,也可能用到点到点传输。如Internet网,IP及以下各层采用点到点传输,4层以上采用端到端传输。
32、说说浏览器从输入 URL 到展现页面的全过程?
1、输入地址
2、浏览器查找域名的 IP 地址
3、浏览器向 web 服务器发送一个 HTTP 请求
4、服务器的永久重定向响应
6、服务器处理请求
7、服务器返回一个 HTTP 响应
8、浏览器显示 HTML
9、浏览器发送请求获取嵌入在 HTML 中的资源(如图片、音频、视频、CSS、JS等等)