【八股】计算机网络面试常问问题

您所在的位置:网站首页 syn是什么乐器的缩写 【八股】计算机网络面试常问问题

【八股】计算机网络面试常问问题

2023-07-04 05:46| 来源: 网络整理| 查看: 265

计算机网络面试常问问题 传输协议概述一、TCP详解0. TCP和UDP的使用场景1. TCP 协议简述2. TCP包首部3. TCP 三次握手建立连接4. 为什么需要三次握手?5. TCP 四次挥手关闭连接6. 为什么连接的时候是三次握手,关闭的时候却是四次握手?7. 为什么要等待2MSL?8. 如果已经建立了连接, 但是客户端突发故障了怎么办? 二、TCP是通过什么机制保障可靠性的?1. 确认应答机制(ACK机制)2. 超时重传机制3. 滑动窗口4. 流量控制5. 拥塞控制 三、UDP详解四、TCP 和 UDP区别五、TCP 和 UDP应用场景

传输协议概述

计算机网络体系结构中的物理层、数据链路层以及网络层它们共同解决了将主机通过异构网络互联起来所面临的问题,实现了主机与主机的通信。

但实际上在计算机网络中进行通信的真正实体是位于通信两端主机中的进程。

如何为运行在不同主机上的应用进程提供直接的通信服务是运输层的任务,运输层协议又称为端到端的协议。

运输层向高层用户屏蔽了下面网络核心的细节,它使应用进程看见的就好像是在两个运输层实体之间有一条端到端的逻辑通信信道。

运输层有两个主要的协议:TCP和UDP

TCP的全称是Transmission Control Protocol,它被称为是一种面向连接的协议,这是因为一个应用程序开始向另一个应用程序发送数据之前,这两个进程必须先进行握手,握手是一个逻辑连接,并不是两个主机之间进行真实的握手。UDP的全称是User Datagram Protocol,它被称为是一种面向无连接的协议,对自己提供的连接实施控制。适用于实时应用,例如:IP电话、视频会议、直播等,以报文的方式传输,效率高,即使知道有破坏的包也不进行重发。 一、TCP详解

TCP是面向连接的、可靠的、基于字节流的传输层通信协议。

面向连接:一定是 「一对一」 才能连接,不能像UDP协议可以一个主机同时向多个主机发送消息,也就是一对多是无法做到的;可靠的:无论的网络链路中出现了怎样的链路变化,TCP都可以保证一个报文一定能够到达接收端;字节流:消息是「没有边界」的,所以无论我们消息有多大都可以进行传输。并且消息是「有序的」,当「前一个」消息没有收到的时候,即使它先收到了后面的字节已经 收到,那么也不能扔给应用层去处理,同时对「重复」的报文会自动丢弃。 在这里插入图片描述 0. TCP和UDP的使用场景

TCP应用场景: 效率要求相对低,但对准确性要求相对高的场景。因为传输中需要对数据确认、重发、排序等操作,相比之下效率没有UDP高。例如:文件传输(准确高要求高、但是速度可以相对慢)、接受邮件、远程登录。

UDP应用场景: 效率要求相对高,对准确性要求相对低的场景。例如:QQ聊天、在线视频、网络语音电话(即时通讯,速度要求高,但是出现偶尔断续不是太大问题,并且此处完全不可以使用重发机制)、广播通信(广播、多播)。

1. TCP 协议简述

TCP 提供面向有连接的通信传输,面向有连接是指在传送数据之前必须先建立连接,数据传送完成后要释放连接。无论哪一方向另一方发送数据之前,都必须先在双方之间建立一条连接。在TCP/IP协议中,TCP协议提供可靠的连接服务,连接是通过三次握手进行初始化的。

同时由于传输控制协议(TCP,Transmission Control Protocol)是一种面向连接的、可靠的、基于字节流的传输层通信协议,TCP是全双工模式,所以需要四次挥手关闭连接。

2. TCP包首部

网络中传输的数据包由两部分组成:一部分是协议所要用到的首部,另一部分是上一层传过来的数据。首部的结构由协议的具体规范详细定义。在数据包的首部,明确标明了协议应该如何读取数据。反过来说,看到首部,也就能够了解该协议必要的信息以及所要处理的数据。包首部就像协议的脸。

所以我们在学习TCP协议之前,首先要知道TCP在网络传输中处于哪个位置,以及它的协议的规范,下面我们就看看TCP首部的网络传输起到的作用: 在这里插入图片描述 下面的图是TCP头部的规范定义,它定义了TCP协议如何读取和解析数据: 在这里插入图片描述

TCP首部承载这TCP协议需要的各项信息,下面我们来分析一下:

TCP端口号: TCP的连接是需要四个要素确定唯一一个连接: (源IP,源端口号)+ (目地IP,目的端口号) 所以TCP首部预留了两个16位作为端口号的存储,而IP地址由上一层IP协议负责传递 源端口号和目地端口各占16位两个字节,也就是端口的范围是2^16=65535 另外1024以下是系统保留的,从1024-65535是用户使用的端口范围

TCP的序号和确认号: 32位序号 seq: Sequence number 缩写seq ,TCP通信过程中某一个传输方向上的字节流的每个字节的序号,通过这个来确认发送的数据有序,比如现在序列号为1000,发送了1000,下一个序列号就是2000。 32位确认号 ack: Acknowledge number 缩写ack,TCP对上一次seq序号做出的确认号,用来响应TCP报文段,给收到的TCP报文段的序号seq加1。

TCP的标志位 每个TCP段都有一个目的,这是借助于TCP标志位选项来确定的,允许发送方或接收方指定哪些标志应该被使用,以便段被另一端正确处理。 用的最广泛的标志是 SYN,ACK 和 FIN,用于建立连接,确认成功的段传输,最后终止连接。 SYN:简写为S,同步标志位,用于建立会话连接,同步序列号; ACK: 简写为.,确认标志位,对已接收的数据包进行确认; FIN: 简写为F,完成标志位,表示我已经没有数据要发送了,即将关闭连接; PSH:简写为P,推送标志位,表示该数据包被对方接收后应立即交给上层应用,而不在缓冲区排队; RST:简写为R,重置标志位,用于连接复位、拒绝错误和非法的数据包; URG:简写为U,紧急标志位,表示数据包的紧急指针域有效,用来保证连接不被阻断,并督促中间设备尽快处理;

总结如下:

源端口号/目的端口号: 表示数据从哪个进程来, 到哪个进程去.32位序号:4位首部长度: 表示该tcp报头有多少个4字节(32个bit)6位保留: 顾名思义, 先保留着, 以防万一6位标志位16位窗口大小:16位检验和: 由发送端填充, 检验形式有CRC校验等. 如果接收端校验不通过, 则认为数据有问题. 此处的校验和不光包含TCP首部, 也包含TCP数据部分.16位紧急指针: 用来标识哪部分数据是紧急数据.选项和数据暂时忽略 3. TCP 三次握手建立连接

所谓三次握手(Three-way Handshake),是指建立一个 TCP 连接时,需要客户端和服务器总共发送3个报文。三次握手的目的是连接服务器指定端口,建立 TCP 连接,并同步连接双方的序列号和确认号,交换 TCP 窗口大小信息。在 socket 编程中,客户端执行 connect() 时。将触发三次握手。

三次握手过程的示意图如下: 在这里插入图片描述

三次握手 第一次: 客户端 - - > 服务器 此时服务器知道了客户端要建立连接了 第二次: 客户端 < - - 服务器 此时客户端知道服务器收到连接请求了 第三次: 客户端 - - > 服务器 此时服务器知道客户端收到了自己的回应 第一次握手: 客户端将TCP报文标志位SYN置为1,随机产生一个序号值seq=J,保存在TCP首部的序列号(Sequence Number)字段里,指明客户端打算连接的服务器的端口,并将该数据包发送给服务器端,发送完毕后,客户端进入SYN_SENT状态,等待服务器端确认。第二次握手: 服务器端收到数据包后由标志位SYN=1知道客户端请求建立连接,服务器端将TCP报文标志位SYN和ACK都置为1,ack=J+1,随机产生一个序号值seq=K,并将该数据包发送给客户端以确认连接请求,服务器端进入SYN_RCVD状态。第三次握手: 客户端收到确认后,检查ack是否为J+1,ACK是否为1,如果正确则将标志位ACK置为1,ack=K+1,并将该数据包发送给服务器端,服务器端检查ack是否为K+1,ACK是否为1,如果正确则连接建立成功,客户端和服务器端进入ESTABLISHED状态,完成三次握手,随后客户端与服务器端之间可以开始传输数据了。

注意: 我们上面写的ack和ACK,不是同一个概念:小写的ack代表的是头部的确认号Acknowledge number, 缩写ack,是对上一个包的序号进行确认的号,ack=seq+1。大写的ACK,则是我们上面说的TCP首部的标志位,用于标志的TCP包是否对上一个包进行了确认操作,如果确认了,则把ACK标志位设置成1。下面我自己做实验,开一个HTTP服务,监听80端口,然后使用Tcpdump命令抓包,看一下TCP三次握手的过程: 在这里插入图片描述我们看下实战中TCP的三次握手过程:

第一次握手,客户端51323端口号向服务器端80号端口发起连接,此时标志位flags=S,即SYN=1标志,表示向服务端发起连接的请求,同时生成序列号seq=84689409第二次握手,服务端标志位flags=[S.],即SYN+ACK标志位设置为1,表示对上一个请求连接的报文进行确认,同时设置ack=seq+1=184689410,生成序列号seq=1893430205第三次握手,客户端对服务端的响应进行确认,所以此时标志位是[.]即ACK=1,同时返回对上一个报文的seq的确认号,ack=1893430206至此,三次握手完成,一个TCP连接建立完成,接下来就是双端传输数据了 4. 为什么需要三次握手?

我们假设client发出的第一个连接请求报文段并没有丢失,而是在某个网络结点长时间的滞留了,以致延误到连接释放以后的某个时间才到达server。本来这是一个早已失效的报文段。但server收到此失效的连接请求报文段后,就误认为是client再次发出的一个新的连接请求。于是就向client发出确认报文段,同意建立连接。假设不采用“三次握手”,那么只要server发出确认,新的连接就建立了。由于现在client并没有发出建立连接的请求,因此不会理睬server的确认,也不会向server发送数据。但server却以为新的运输连接已经建立,并一直等待client发来数据。这样,server的很多资源就白白浪费掉了。所以,采用“三次握手”的办法可以防止上述现象发生。例如刚才那种情况,client不会向server的确认发出确认。server由于收不到确认,就知道client并没有要求建立连接。

TCP 三次握手跟现实生活中的人与人打电话是很类似的:三次握手: “喂,你听得到吗?” “我听得到呀,你听得到我吗?” “我能听到你,今天 balabala……”经过三次的互相确认,大家就会认为对方对听的到自己说话,并且愿意下一步沟通,否则,对话就不一定能正常下去了。

为什么不用两次? 主要是为了防止已经失效的连接请求报文突然又传送到了服务器,从而产生错误。如果使用的是两次握手建立连接,假设有这样一种场景,客户端发送的第一个请求连接并且没有丢失,只是因为在网络中滞留的时间太长了,由于TCP的客户端迟迟没有收到确认报文,以为服务器没有收到,此时重新向服务器发送这条报文,此后客户端和服务器经过两次握手完成连接,传输数据,然后关闭连接。此时之前滞留的那一次请求连接,因为网络通畅了, 到达了服务器,这个报文本该是失效的,但是,两次握手的机制将会让客户端和服务器再次建立连接,这将导致不必要的错误和资源的费。

如果采用的是三次握手,就算是那一次失效的报文传送过来了,服务端接受到了那条失效报文并且回复了确认报文,但是客户端不会再次发出确认。由于服务器收不到确认,就知道客户端并没有请求连接。

5. TCP 四次挥手关闭连接

四次挥手即终止TCP连接,就是指断开一个TCP连接时,需要客户端和服务端总共发送4个包以确认连接的断开。在socket编程中,这一过程由客户端或服务端任一方执行close来触发。

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

四次挥手过程的示意图如下: 在这里插入图片描述 挥手请求可以是Client端,也可以是Server端发起的,我们假设是Client端发起:

第一次挥手: Client端发起挥手请求,向Server端发送标志位是FIN报文段,设置序列号seq,此时,Client端进入FIN_WAIT_1状态,这表示Client端没有数据要发送给Server端了。

第二次分手:Server端收到了Client端发送的FIN报文段,向Client端返回一个标志位是ACK的报文段,ack设为seq加1,Client端进入FIN_WAIT_2状态,Server端告诉Client端,我确认并同意你的关闭请求。

第三次分手: Server端向Client端发送标志位是FIN的报文段,请求关闭连接,同时Client端进入LAST_ACK状态。

第四次分手 : Client端收到Server端发送的FIN报文段,向Server端发送标志位是ACK的报文段,然后Client端进入TIME_WAIT状态。Server端收到Client端的ACK报文段以后,就关闭连接。此时,Client端等待2MSL的时间后依然没有收到Server的重发FIN报文,则证明Server端已正常关闭,那好,Client端也可以关闭连接了。 在这里插入图片描述 数据传输完毕后,双方都可以释放连接.

此时客户端和服务器都是处于ESTABLISHED状态,然后客户端主动断开连接,服务器被动断开连接.

1, 客户端进程发出连接释放报文,并且停止发送数据。

释放数据报文首部,FIN=1,其序列号为seq=u(等于前面已经传送过来的数据的最后一个字节的序号加1),此时客户端进入FIN-WAIT-1(终止等待1)状态。 TCP规定,FIN报文段即使不携带数据,也要消耗一个序号。

2, 服务器收到连接释放报文,发出确认报文,ACK=1,确认序号为 u+1,并且带上自己的序列号seq=v,此时服务端就进入了CLOSE-WAIT(关闭等待)状态。

TCP服务器通知高层的应用进程,客户端向服务器的方向就释放了,这时候处于半关闭状态,即客户端已经没有数据要发送了,但是服务器若发送数据,客户端依然要接受。这个状态还要持续一段时间,也就是整个CLOSE-WAIT状态持续的时间。

3, 客户端收到服务器的确认请求后,此时客户端就进入FIN-WAIT-2(终止等待2)状态,等待服务器发送连接释放报文(在这之前还需要接受服务器发送的最终数据)

4, 服务器将最后的数据发送完毕后,就向客户端发送连接释放报文,FIN=1,确认序号为v+1,由于在半关闭状态,服务器很可能又发送了一些数据,假定此时的序列号为seq=w,此时,服务器就进入了LAST-ACK(最后确认)状态,等待客户端的确认。

5, 客户端收到服务器的连接释放报文后,必须发出确认,ACK=1,确认序号为w+1,而自己的序列号是u+1,此时,客户端就进入了TIME-WAIT(时间等待)状态。注意此时TCP连接还没有释放,必须经过2∗MSL(最长报文段寿命)的时间后,当客户端撤销相应的TCB后,才进入CLOSED状态。

6, 服务器只要收到了客户端发出的确认,立即进入CLOSED状态。同样,撤销TCB后,就结束了这次的TCP连接。可以看到,服务器结束TCP连接的时间要比客户端早一些。

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

建立连接时因为当Server端收到Client端的SYN连接请求报文后,可以直接发送SYN+ACK报文。其中ACK报文是用来应答的,SYN报文是用来同步的。所以建立连接只需要三次握手。由于TCP协议是一种面向连接的、可靠的、基于字节流的运输层通信协议,TCP是全双工模式。

这就意味着,关闭连接时,当Client端发出FIN报文段时,只是表示Client端告诉Server端数据已经发送完毕了。当Server端收到FIN报文并返回ACK报文段,表示它已经知道Client端没有数据发送了,但是Server端还是可以发送数据到Client端的,所以Server很可能并不会立即关闭SOCKET,直到Server端把数据也发送完毕。

当Server端也发送了FIN报文段时,这个时候就表示Server端也没有数据要发送了,就会告诉Client端,我也没有数据要发送了,之后彼此就会愉快的中断这次TCP连接。

通俗解答: 建立连接的时候, 服务器在LISTEN状态下,收到建立连接请求的SYN报文后,把ACK和SYN放在一个报文里发送给客户端。

而关闭连接时,服务器收到对方的FIN报文时,仅仅表示对方不再发送数据了但是还能接收数据,而自己也未必全部数据都发送给对方了,所以己方可以立即关闭,也可以发送一些数据给对方后,再发送FIN报文给对方来表示同意现在关闭连接,因此,己方ACK和FIN一般都会分开发送,从而导致多了一次。

7. 为什么要等待2MSL?

MSL:报文段最大生存时间,它是任何报文段被丢弃前在网络内的最长时间。

有以下两个原因:

第一点:保证TCP协议的全双工连接能够可靠关闭: 由于IP协议的不可靠性或者是其它网络原因,导致了Server端没有收到Client端的ACK报文,那么Server端就会在超时之后重新发送FIN,如果此时Client端的连接已经关闭处于CLOESD状态,那么重发的FIN就找不到对应的连接了,从而导致连接错乱,所以,Client端发送完最后的ACK不能直接进入CLOSED状态,而要保持TIME_WAIT,当再次收到FIN的收,能够保证对方收到ACK,最后正确关闭连接。

第二点:保证这次连接的重复数据段从网络中消失 如果Client端发送最后的ACK直接进入CLOSED状态,然后又再向Server端发起一个新连接,这时不能保证新连接的与刚关闭的连接的端口号是不同的,也就是新连接和老连接的端口号可能一样了,那么就可能出现问题:如果前一次的连接某些数据滞留在网络中,这些延迟数据在建立新连接后到达Client端,由于新老连接的端口号和IP都一样,TCP协议就认为延迟数据是属于新连接的,新连接就会接收到脏数据,这样就会导致数据包混乱。所以TCP连接需要在TIME_WAIT状态等待2倍MSL,才能保证本次连接的所有数据在网络中消失。

通俗解释: MSL(Maximum Segment Lifetime 报文最大生存时间,它是任何报文在网络上存在的最长时间,超过这个时间报文将被丢弃。),TCP允许不同的实现可以设置不同的MSL值。

第一,保证客户端发送的最后一个ACK报文能够到达服务器,因为这个ACK报文可能丢失,站在服务器的角度看来,我已经发送了FIN+ACK报文请求断开了,客户端还没有给我回应,应该是我发送的请求断开报文它没有收到,于是服务器又会重新发送一次,而客户端就能在这个2MSL时间段内收到这个重传的报文,接着给出回应报文,并且会重启2MSL计时器。

第二,防止类似与“三次握手”中提到了的“已经失效的连接请求报文段”出现在本连接中。客户端发送完最后一个确认报文后,在这个2MSL时间中,就可以使本连接持续的时间内所产生的所有报文段都从网络中消失。这样新的连接中不会出现旧连接的请求报文。

8. 如果已经建立了连接, 但是客户端突发故障了怎么办?

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

二、TCP是通过什么机制保障可靠性的?

CP(传输控制协议)是一种基于连接的、可靠性强的传输层协议,为上层应用程序提供端到端的面向连接的通信服务。其通过以下机制保障数据的可靠性:

1、字节流传输:TCP采用字节流传输的方式,将应用层发送的数据划分成以字节为单位的报文段(Segment),并进行序列号标记,以确保数据传输的有序性。

2、确认重传机制:TCP采用三次握手建立连接,并在通信过程中采用确认和重传机制,以确保数据能够有效传送。当接收方收到报文段后,都会进行确认(Ack)操作。如果发送方没有收到确认,则会重新传送该报文。

3、滑动窗口机制:TCP利用滑动窗口机制实现流量控制和拥塞控制。通过限制发送方窗口大小,防止发送速度过快,而接收方处理不及时导致的包丢失等问题。同时,可以根据网络拥塞情况来动态调整窗口大小,保证网络的稳定性和可靠性。

4、头部校验和:在TCP传输过程中,每个报文段都会添加一个头部校验和,以检测数据在传输过程中是否损坏或者被篡改。如果发现数据损坏,则会进行重传,以确保数据的完整性和准确性。

TCP通过以上机制,保证了数据在传输过程中的可靠性,并且具有高效、稳定的特点,成为互联网传输层协议的重要组成部分。

1. 确认应答机制(ACK机制)

在这里插入图片描述TCP将每个字节的数据都进行了编号, 即为序列号.

在这里插入图片描述每一个ACK都带有对应的确认序列号(ack), 意思是告诉发送者, 我已经收到了哪些数据; 下一次你要从哪里开始发.

比如, 客户端向服务器发送了1005字节的数据, 服务器返回给客户端的确认序号是1003, 那么说明服务器只收到了1-1002的数据.

1003, 1004, 1005都没收到.

此时客户端就会从1003开始重发.

2. 超时重传机制

在这里插入图片描述主机A发送数据给B之后, 可能因为网络拥堵等原因, 数据无法到达主机B

如果主机A在一个特定时间间隔内没有收到B发来的确认应答, 就会进行重发

但是主机A没收到确认应答也可能是ACK丢失了. 在这里插入图片描述 这种情况下, 主机B会收到很多重复数据.

那么TCP协议需要识别出哪些包是重复的, 并且把重复的丢弃.

这时候利用前面提到的序列号, 就可以很容易做到去重.

超时时间如何确定?

最理想的情况下, 找到一个最小的时间, 保证 “确认应答一定能在这个时间内返回”.

但是这个时间的长短, 随着网络环境的不同, 是有差异的.

如果超时时间设的太长, 会影响整体的重传效率; 如果超时时间设的太短, 有可能会频繁发送重复的包.

TCP为了保证任何环境下都能保持较高性能的通信, 因此会动态计算这个最大超时时间.

Linux中(BSD Unix和Windows也是如此), 超时以500ms为一个单位进行控制, 每次判定超时重发的超时时间都是500ms的整数倍.如果重发一次之后, 仍然得不到应答, 等待 2*500ms 后再进行重传. 如果仍然得不到应答, 等待 4500ms 进行重传.依次类推, 以指数形式递增. 累计到一定的重传次数, TCP认为网络异常或者对端主机出现异常, 强制关闭连接.

3. 滑动窗口

刚才我们讨论了确认应答机制, 对每一个发送的数据段, 都要给一个ACK确认应答. 收到ACK后再发送下一个数据段.

这样做有一个比较大的缺点, 就是性能较差. 尤其是数据往返时间较长的时候.

那么我们可不可以一次发送多个数据段呢?

例如这样:

在这里插入图片描述一个概念: 窗口

窗口大小指的是无需等待确认应答就可以继续发送数据的最大值.

上图的窗口大小就是4000个字节 (四个段).

发送前四个段的时候, 不需要等待任何ACK, 直接发送

收到第一个ACK确认应答后, 窗口向后移动, 继续发送第五六七八段的数据…

因为这个窗口不断向后滑动, 所以叫做滑动窗口.

操作系统内核为了维护这个滑动窗口, 需要开辟发送缓冲区来记录当前还有哪些数据没有应答

只有ACK确认应答过的数据, 才能从缓冲区删掉. 在这里插入图片描述 如果出现了丢包, 那么该如何进行重传呢?

此时分两种情况讨论:

数据包已经收到, 但确认应答ACK丢了.

在这里插入图片描述这种情况下, 部分ACK丢失并无大碍, 因为还可以通过后续的ACK来确认对方已经收到了哪些数据包.\

数据包丢失

在这里插入图片描述 当某一段报文丢失之后, 发送端会一直收到 1001 这样的ACK, 就像是在提醒发送端 “我想要的是 1001”

如果发送端主机连续三次收到了同样一个 “1001” 这样的应答, 就会将对应的数据 1001 - 2000 重新发送

这个时候接收端收到了 1001 之后, 再次返回的ACK就是7001了

因为2001 - 7000接收端其实之前就已经收到了, 被放到了接收端操作系统内核的接收缓冲区中.

这种机制被称为 “高速重发控制” ( 也叫 “快重传” )

4. 流量控制

接收端处理数据的速度是有限的. 如果发送端发的太快, 导致接收端的缓冲区被填满, 这个时候如果发送端继续发送, 就会造成丢包, 进而引起丢包重传等一系列连锁反应.

因此TCP支持根据接收端的处理能力, 来决定发送端的发送速度.

这个机制就叫做 流量控制(Flow Control)

接收端将自己可以接收的缓冲区大小放入 TCP 首部中的 “窗口大小” 字段,

通过ACK通知发送端;

窗口大小越大, 说明网络的吞吐量越高;

接收端一旦发现自己的缓冲区快满了, 就会将窗口大小设置成一个更小的值通知给发送端;

发送端接受到这个窗口大小的通知之后, 就会减慢自己的发送速度;

如果接收端缓冲区满了, 就会将窗口置为0;

这时发送方不再发送数据, 但是需要定期发送一个窗口探测数据段, 让接收端把窗口大小再告诉发送端 在这里插入图片描述 那么接收端如何把窗口大小告诉发送端呢?

我们的TCP首部中, 有一个16位窗口大小字段, 就存放了窗口大小的信息;

16位数字最大表示65536, 那么TCP窗口最大就是65536字节么?

实际上, TCP首部40字节选项中还包含了一个窗口扩大因子M, 实际窗口大小是窗口字段的值左移 M 位(左移一位相当于乘以2).

5. 拥塞控制

虽然TCP有了滑动窗口这个大杀器, 能够高效可靠地发送大量数据.

但是如果在刚开始就发送大量的数据, 仍然可能引发一些问题.

因为网络上有很多计算机, 可能当前的网络状态已经比较拥堵.

在不清楚当前网络状态的情况下, 贸然发送大量数据, 很有可能雪上加霜.

因此, TCP引入 慢启动 机制, 先发少量的数据, 探探路, 摸清当前的网络拥堵状态以后, 再决定按照多大的速度传输数据. 在这里插入图片描述 在此引入一个概念 拥塞窗口

发送开始的时候, 定义拥塞窗口大小为1;

每次收到一个ACK应答, 拥塞窗口加1;

每次发送数据包的时候, 将拥塞窗口和接收端主机反馈的窗口大小做比较, 取较小的值作为实际发送的窗口

像上面这样的拥塞窗口增长速度, 是指数级别的.

“慢启动” 只是指初使时慢, 但是增长速度非常快.

为了不增长得那么快, 此处引入一个名词叫做 慢启动的阈值, 当拥塞窗口的大小超过这个阈值的时候, 不再按照指数方式增长, 而是按照线性方式增长. 在这里插入图片描述 当TCP开始启动的时候, 慢启动阈值等于窗口最大值

在每次超时重发的时候, 慢启动阈值会变成原来的一半, 同时拥塞窗口置回1

少量的丢包, 我们仅仅是触发超时重传;

大量的丢包, 我们就认为是网络拥塞;

当TCP通信开始后, 网络吞吐量会逐渐上升;

随着网络发生拥堵, 吞吐量会立刻下降.

拥塞控制, 归根结底是TCP协议想尽可能快的把数据传输给对方, 但是又要避免给网络造成太大压力的折中方案.

三、UDP详解

UDP不提供复杂的控制机制,利用IP提供面向「无连接」的通信服务。

UDP的全称是用户数据报协议(UDP, User Datagram Protocol), UDP为应用程序提供了一种 无需建立连接就可以发送封装的IP数据包的方法。如果应用程序开发人员选择的是UDP而不是TCP的话,那么该应用程序相当于就是和IP直接打交道的

UDP协议的特点就是无连接、不可靠、面向数据报的,整个过程就像是一个寄信的过程,每次接收和发送数据均是整条进行发送。

无连接: 知道对端的IP和端口号就直接进行传输, 不需要建立连接.不可靠: 没有确认机制, 没有重传机制; 如果因为网络故障该段无法发到对方, UDP协议层也不会给应用层返回任何错误信息.面向数据报: 不能够灵活的控制读写数据的次数和数量.

UDP协议真的非常简单,头部只有8个字节(64位),UDP的头部格式如下:

在这里插入图片描述

目标和源端口:主要是告诉UDP 协议应该把报文发给哪个进程。

包长度:该字段保存了UDP首部的长度跟数据的长度之和。

校验和:校验和是为了提供可靠的UDP首部和数据而设计。

四、TCP 和 UDP区别

1:连接

TCP是面向连接的传输层协议,传输数据前先要建立连接。UDP是不需要连接,即刻传输数据。

2:服务对象

TCP是一对一的两点服务,即一条连接只有两个端点。UDP 支持一对一、一对多、多对多的交互通信

3:可靠性

TCP 是可靠交付数据的,数据可以无差错、不丢失、不重复、按需到达。UDP 是尽最大努力交付,不保证可靠交付数据。

4:拥塞控制、流量控制

TCP有拥塞控制和流量控制机制,保证数据传输的安全性。UDP则没有,即使网络非常拥堵了,也不会影响UDP的发送速率。

5:首部开销

TCP首部长度较长,会有一定的开销,首部在没有使用「选项/字是20个字节,如果使用了「选项」字段则会变长的UDP 首部只有8个字节,并且是固定不变的,开销较小。 五、TCP 和 UDP应用场景

由于TCP是面向连接,能保证数据的可靠性交付,因此经常用于:

FTP 文件传输HTTP / HTTPS

由于UDP面向无连接,它可以随时发送数据,再加上UDP本身的处理既简单又高效,因此经常用于:

包总量较少的通信,如DNS、SNMP等视频、音频等多媒体通信广播通信适用于实时应用,例如:IP电话、视频会议、直播等


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3