一、计算机网络体系结构

0. 概述

我们把计算机网络的各层及协议集合,称为网络的体系结构。

层与协议:每一层都是为了完成一种功能,为了完成这些功能,需要遵循一些规则,这些规则就是协议,每一层都定义了一些协议。

国际标准化组织ISO 于1981年正式推荐了一个网络系统结构—-七层参考模型,叫做开放系统互连模型(Open System Interconnection,OSI)。由于这个标准模型的建立,使得各种计算机网络向它靠拢,大大推动了网络通信的发展。
但由于OSI体系结构太复杂,在实际应用中TCP/IP的四层体系结构得到广泛应用,作为折中,在学习中一般学习五层协议体系机构。各体系结构如下图:

计算机网络面试题 - 图1

总结

计算机网络面试题 - 图2

1. 请介绍OSI七层网络体系结构

为什么分层

  • 计算机网络是个非常复杂的系统,分层可将庞大而复杂的问题,转化为若干较小的局部问题,而这些较小的局部问题就比较容易研究和处理
  • 支持异构网络的互联互通
  • 插槽式的设计,使得各模块耦合性低,便于升级与替换

七层分别负责的内容(功能)
OSI 模型把网络通信的工作分为 7 层,从下到上分别是物理层、数据链路层、网络层、传输层、会话层、表示层和应用层

  1. 应用层
    任务:提供系统与用户的接口
    功能:
    a. 文件传输
    b. 访问和管理
    c. 电子邮件服务

协议:FTP(21端口,文件传输协议)、SSH(22端口,远程登陆)、TELNET(23端口、远程登录)、SMTP(25端口,发送邮件)、POP3(110端口,接收邮件)、HTTP(80端口,超文本传输协议),DNS(53端口,运行在UDP上,域名解析服务)

  1. 表示层
    负责处理在两个内部数据表示结构不同的通信系统之间交换信息的表示格式,为数据加密和解密以及为提高传输效率提供必需的数据压缩以及解压等功能。
  2. 会话层
    任务:不同主机上各进程间的对话
    功能:管理主机间的会话进程,包括建立、管理以及终止进程间的会话。是一种端到端的服务
  3. 运输层
    任务:负责主机中两个进程之间的通信,传输应用层报文
    功能:a. 为端到端连接提供可靠的服务
    b. 为端到端连接提供流量控制、差错控制、服务质量等管理服务
    传输单位:报文段(TCP)或用户数据报(UDP)
    协议:TCP、UDP
  4. 网络层
    任务:a. 将运输层传下来的报文段封装成分组
    b. 选择合适的路由,使得传输层传下来的分组能够交付到目的主机
    功能:

    a. 为传输层提供服务
    b. 组包和拆包
    c. 路由选择
    d. 拥塞控制
    传输单位:数据段
    所实现的硬件:路由器(根据IP地址进行寻址)
    协议:ICMP(Internet控制报文协议)、ARP(地址解析协议)、RARP、IP、IGMP、OSPF

  5. 数据链路层

    任务:将网络层传输下来的IP数据报组装成帧, 在两个相邻的节点间的链路上传送帧。
    功能:a. 链路连接的建立、拆除和分离 b. 帧定界和帧同步
    c. 差错检测(奇偶校验、循环冗余校验)
    传输单位:帧
    所实现的硬件:交换机(根据MAC地址进行寻址)、网桥
    协议:HDLC、SDLC、STP、ARQ(自动重传请求) 、点对点协议(Point-to-Point Protocol)、以太网(Ethernet);

  6. 物理层
    任务:透明地传输比特流,尽可能屏蔽掉具体的传输介质和物理设备的差异,使其上面的数据链路层不必考虑网络的具体传输介质是什么。“透明传送比特流”表示经实际电路传送后的比特流没有发生变化,对传送的比特流来说,这个电路好像是看不见的。
    功能:为数据段设备提供传送数据通路
    传输单位:比特
    所实现的硬件:集线器,中继器

    2. 请介绍五层网络体系结构

    五层网络体系结构分别为:应用层、运输层、网络层、数据链路层、物理层。各层功能分别如下:

第五层——应用层(application layer)
(1) 应用层(application layer):是体系结构中的最高,直接为用户的应用进程提供服务。
(2) 在因特网中的应用层协议很多,如支持万维网应用的HTTP协议,支持电子邮件的SMTP协议,支持文件传送的FTP协议等等。

第四层——运输层(transport layer)
(1) 运输层(transport layer):负责向两个主机中进程之间的通信提供服务。由于一个主机可同时运行多个进程,因此运输层有复用分用的功能。
a. 复用,就是多个应用层进程可同时使用下面运输层的服务。
b. 分用,就是把收到的信息分别交付给上面应用层中相应的进程。
(2) 运输层主要使用以下两种协议:
a. 传输控制协议TCP(Transmission Control Protocol): 面向连接的,数据传输的单位是报文段,能够提供可靠的交付。
b. 用户数据包协议UDP(User Datagram Protocol): 无连接的,数据传输的单位是用户数据报,不保证提供可靠的交付,只能提供“尽最大努力交付”。

第三层——网络层(network layer)
网络层(network layer)主要包括以下两个任务:
(1) 负责为分组交换网上的不同主机提供通信服务。在发送数据时,网络层把运输层产生的报文段或用户数据报封装成分组或包进行传送。在TCP/IP体系中,由于网络层使用IP协议,因此分组也叫做IP数据报,或简称为数据报。
(2) 选中合适的路由,使源主机运输层所传下来的分组,能够通过网络中的路由器找到目的主机。

第二层——数据链路层(data link layer)
数据链路层(data link layer):常简称为链路层,我们知道,两个主机之间的数据传输,总是在一段一段的链路上传送的,也就是说,在两个相邻结点之间传送数据是直接传送的(点对点),这时就需要使用专门的链路层的协议。
在两个相邻结点之间传送数据时,数据链路层将网络层交下来的IP数据报组装成帧(framing),在两个相邻结点之间的链路上“透明”地传送帧中的数据。
每一帧包括数据和必要的控制信息(如同步信息、地址信息、差错控制等)。典型的帧长是几百字节到一千多字节。
注意:”透明”是一个很重要的术语。它表示,某一个实际存在的事物看起来却好像不存在一样。”在数据链路层透明传送数据”表示无论什么样的比特组合的数据都能够通过这个数据链路层。因此,对所传送的数据来说,这些数据就“看不见”数据链路层。或者说,数据链路层对这些数据来说是透明的。
(1) 在接收数据时,控制信息使接收端能知道一个帧从哪个比特开始和到哪个比特结束。这样,数据链路层在收到一个帧后,就可从中提取出数据部分,上交给网络层。
(2) 控制信息还使接收端能检测到所收到的帧中有无差错。如发现有差错,数据链路层就简单地丢弃这个出了差错的帧,以免继续传送下去白白浪费网络资源。如需改正错误,就由运输层的TCP协议来完成。

第一层——物理层(physical layer)
物理层(physical layer):在物理层上所传数据的单位是比特。物理层的任务就是透明地传送比特流。

3. 讲一下TCP/IP协议

1.TCP/IP协议定义
TCP/IP(Transmission Control Protocol/Internet Protocol,传输控制协议/网际协议)是指能够在多个不同网络间实现信息传输的协议簇。TCP/IP协议不仅仅指的是TCP和IP两个协议,而是指一个由FTP、SMTP、TCP、UDP、IP等协议构成的协议簇, 只是因为在TCP/IP协议中TCP协议和IP协议最具代表性,所以被称为TCP/IP协议。

2.TCP/IP协议组成
TCP/IP结构模型分为应用层、传输层、网络层、链路层(网络接口层)四层,以下是各层的详细介绍:
(1)应用层
应用层是TCP/IP协议的第一层,是直接为应用进程提供服务的。
a. 对不同种类的应用程序它们会根据自己的需要来使用应用层的不同协议,邮件传输应用使用了SMTP协议、万维网应用使用了HTTP协议、远程登录服务应用使用了有TELNET协议。(应用层)
b. 应用层还能加密、解密、格式化数据。(表示层)
c. 应用层可以建立或解除与其他节点的联系,这样可以充分节省网络资源。(会话层)
(2)传输层
作为TCP/IP协议的第二层,运输层在整个TCP/IP协议中起到了中流砥柱的作用。且在运输层中,TCP和UDP也同样起到了中流砥柱的作用。
(3)网络层
网络层在TCP/IP协议中的位于第三层。在TCP/IP协议中网络层可以进行网络连接的建立和终止以及IP地址的寻找等功能。
(4)链路层(网络接口层)
在TCP/IP协议中,网络接口层位于第四层。由于网络接口层兼并了物理层和数据链路层。所以,网络接口层既是传输数据的物理媒介,也可以为网络层提供一条准确无误的线路。

3.TCP/IP协议特点
TCP/IP协议能够迅速发展起来并成为事实上的标准,是它恰好适应了世界范围内数据通信的需要。它有以下特点:
(1)协议标准是完全开放的,可以供用户免费使用,并且独立于特定的计算机硬件与操作系统;
(2)独立于网络硬件系统,可以运行在广域网,更适合于互联网;
(3)网络地址统一分配,网络中每一设备和终端都具有一个唯一地址;
(4)高层协议标准化,可以提供多种多样可靠网络服务。

二、网络层

1. 说一说你对ARP协议的理解

ARP协议即地址解析协议,是根据IP地址获取MAC地址的一个网络层协议。

  1. 工作原理
    ARP首先会发起一个请求数据包,数据包的首部包含了目标主机的IP地址,然后这个数据包会在链路层进行再次包装,生成以太网数据包,最终由以太网广播给子网内的所有主机,每一台主机都会接收到这个数据包,并取出包头里的IP地址,然后和自己的IP地址进行比较,如果相同就返回自己的MAC地址,如果不同就丢弃该数据包。ARP接收返回消息,以此确定目标机的MAC地址;与此同时,ARP还会将返回的MAC地址与对应的IP地址存入本机ARP缓存中并保留一定时间,下次请求时直接查询ARP缓存以节约资源。

如果所要找的主机和源主机不在同一个局域网上,那么就要通过 ARP 找到一个位于本局域网上的某个路由器的硬件地址,然后把分组发送给这个路由器,让这个路由器把分组转发给下一个网络。剩下的工作就由下一个网络来做。

  1. 工作过程
    主机A的IP地址为192.168.1.1,MAC地址为0A-11-22-33-44-01;
    主机B的IP地址为192.168.1.2,MAC地址为0A-11-22-33-44-02;
    当主机A要与主机B通信时,地址解析协议可以将主机B的IP地址(192.168.1.2)解析成主机B的MAC地址,以下为工作流程:
    第1步:根据主机A上的路由表内容,IP确定用于访问主机B的转发IP地址是192.168.1.2。然后A主机在自己的本地ARP缓存中检查主机B的匹配MAC地址。
    第2步:如果主机A在ARP缓存中没有找到映射,它将询问192.168.1.2的硬件地址,从而将ARP请求帧广播到本地网络上的所有主机。源主机A的IP地址和MAC地址都包括在ARP请求中。本地网络上的每台主机都接收到ARP请求并且检查是否与自己的IP地址匹配。如果主机发现请求的IP地址与自己的IP地址不匹配,它将丢弃ARP请求。
    第3步:主机B确定ARP请求中的IP地址与自己的IP地址匹配,则将主机A的IP地址和MAC地址映射添加到本地ARP缓存中。
    第4步:主机B将包含其MAC地址的ARP回复消息直接发送回主机A。
    第5步:当主机A收到从主机B发来的ARP回复消息时,会用主机B的IP和MAC地址映射更新ARP缓存。本机缓存是有生存期的,生存期结束后,将再次重复上面的过程。主机B的MAC地址一旦确定,主机A就能向主机B发送IP通信了。

2. IP地址的分类?

  1. 分类编址的IPv4地址

路由器仅根据网络号net-id来转发分组,当分组到达目的网络的路由器之后,再按照主机号host-id将分组交付给主机;同一网络上的所有主机的网络号相同。
计算机网络面试题 - 图3

  1. 划分子网的IPv4地址

从主机号host-id借用若干个比特作为子网号subnet-id;
子网掩码:网络号和子网号都为1,主机号为0;数据报仍然先按照网络号找到目的网络,发送到路由器,路由器再按照网络号和子网号找到目的子网:将子网掩码与目标地址逐比特与操作,若结果为某个子网的网络地址,则送到该子网。

为什么划分子网? 理由很简单,为了节省IP地址。IPv4当初设计的时候只是为了实验,只有2^32个地址。但是随着现在PC、网络设备和移动设备越来越多,需要的IP地址也越来越多,所以IPv4的地址资源已经枯竭,而IPv6又没有开始普及,所以只能尽量节省地址。比如定义了私有地址、开发了NAT技术以及子网划分等。子网划分为什么能节省地址,举个简单的例子:比如在网络上有两个路由器直连,这两个路由器只是为了连接网络使用,之间没有任何PC、服务器或者其他资源的时候,如果不进行子网划分的话就会占用至少一个网段的IP地址,但是这个网段只需要两个就够了,那么剩下的252的地址就浪费了。但是经过子网划分之后,划分成/30掩码这个网段就只有4个地址,除去网络号和广播地址,正好有两个可用IP分配给两个设备,这样就会大大的节省IP地址资源了。

计算机网络面试题 - 图4

  1. 无分类编址的IPv4地址

计算机网络面试题 - 图5

3. IP协议包含哪些字段?

IP所包含字段结构图如下:
IP字段.jpg
IP协议包含字段如下:

  • 4位版本号:指定IP协议的版本,对于IPv4来说就是4
  • 4位头部长度:IP头部长度有多少个4字节(以4字节作为单位),所以头部最大长度就是15*4=60字节
  • 8位服务类型:3位优先权(已弃用),4位TOS字段,1位保留字段(必须设置为0)。4位TOS为:最小延时,最大吞吐量,最高可靠性,最小成本,这四个只能选择一个
  • 16位总长度:IP数据报整体占多少字节
  • 16位标识:唯一的标识主机发送的报文,IP报文在数据链路层被分片,那么每一个片中的标识都是相同的
  • 3位标志字段:第一位保留,第二位置1表示进制分片(报文长度超过MTU,丢弃报文),第三位更多分片,最后一个分片是1,其他是0
  • 13位分片偏移:相对于原始IP报文开始处的偏移
  • 8位生存时间:数据报到达目的地的最大报文跳数,每经过一个路由,TTL-=1,一直到0都没有到达目的地,报文丢弃。
  • 8位协议:表示上层协议类型,把IP交给TCP还是UDP,其中ICMP是1,TCP是6,UDP是17
  • 16位头部校验和:使用CRC校验,鉴别头部是否损坏
  • 32位源地址和32位目标地址:表示发送端和接收端

4. 网际报文控制协议ICMP

image.png

  • 为了更有效地转发IP数据报和提高交付成功的机会,在网际层使用了网际报文控制协议
  • ICMP报文被封装在IP数据报中发送
  • 主机或路由器使用ICMP来发送查询报文和差错报告报文
  • 查询报文(Echo Request与 Echo Reply):
    • 定义:发送端主动发起请求,并且获取到应答。
    • 常见应用:Ping
    • Ping 就是主动请求,获取到主动应答。但是 Ping 是在原生的 ICMP 中添加了自定义格式区域。例如 Ping 中放了发送的请求时间,以此计算出路程。所以,其实在 Ping 的报文中会加入序号,以用来区分数据包,从而提高计算时间或者路程的准确性。
  • 差错报告报文共有以下五种:
    • 终点不可达:当路由器或主机不能交付数据报时,就向源点发送终点不可达报文
    • 源点抑制:当路由器或主机由于拥塞而丢弃数据报时,就向源点发送源点抑制报文,使源点知道应该将数据报的发送速率放慢
    • 时间超过:当路由器收到一个目的IP地址不是自己的IP数据报,会将其生存时间TTL字段的值减1。若结果不为0,则将该数据报转发出去;若结果为0,除丢弃该IP数据报外,还要向源点发送时间超过报文
    • 参数问题:当路由器或目的主机收到IP数据报后,根据其首部中的检验和字段发现首部在传输过程中出现了误码,就丢弃该数据报,并向源点发送参数问题报文
    • 改变路由:路由器把改变路由报文发送给主机,让主机知道下次应将数据报发送给另外的路由器

ping的运作原理是向目标主机传出一个ICMP echo@要求数据包,并等待接收echo回应数据包。程序会按时间和成功响应的次数估算丢失数据包率(丢包率)和数据包往返时间(网络时延,Round-trip delay time)。
计算机网络面试题 - 图8计算机网络面试题 - 图9

5. 虚拟专用网络VPN

利用公有的因特网作为本机构各专用网之间的通信载体,这样的专用网又称为虚拟专用网。
由于IPv4地址的紧缺,一个机构能够申请到的IPv4地址数量往往远小于本机构所拥有的主机数量。因此,虚拟专用网中的各主机所分配的地址应该是本机构可自由分配的专用地址,而不是需要申请的、在互联网上使用的公有地址。
如下图所示,同一机构内不同部门的内部网络所构成的虚拟专用网VPN又称为内联网VPN
有时一个机构的VPN需要某些外部机构(通常是合作伙伴)参加进来,这样的VPN就称为外联网VPN
在外地工作的员工需要访问公司内部的专用网络时,只要在任何地点接入到因特网,运行驻留在员工PC中的VPN软件,在员工的PC和公司的主机之间建立VPN隧道,即可访问专用网络中的资源。这种VPN成为远程接入VPN
计算机网络面试题 - 图10

6. 网络地址转换NAT

虽然互联网采用了无分类编址方式来减缓IPv4地址空间耗尽的速度,但由于互联网用户数目的激增,IPv4地址空间即将面临耗尽的危险仍然没有被解除。
1994年提出了一种网络地址转换NAT的方法再次缓解了IPv4地址空间即将耗尽的问题。
NAT能使大量使用内部专用地址的专用网络用户共享少量外部全球地址来访问因特网上的主机和资源。
计算机网络面试题 - 图11
计算机网络面试题 - 图12
计算机网络面试题 - 图13

三、运输层

TCP协议详解(TCP报文、三次握手、四次挥手、TIME_WAIT状态、滑动窗口、拥塞控制、粘包问题、状态转换图)

1. TCP 报文段首部格式

首部字段详细图.png
TCP首部包括20字节的固定首部部分及长度可变的其他选项,所以TCP首部长度可变。20个字节又分为5部分,每部分4个字节32位,如图中的5行,每行表示32位。

  1. 源端口和目的端口字段——各占 2 字节(16位)。端口是运输层与应用层的服务接口。运输层的复用和分用功能都要通过端口才能实现。
  2. 序号字段——占 4 字节。TCP 连接中传送的数据流中的每一个字节都编上一个序号。序号字段的值则指的是本报文段所发送的数据的第一个字节的序号。比如分组的第一个数据包由文件的14个字节数据组成,那么该数据包所添加的序号就是1,同理第二个数据包由文件的59个字节数据组成,那么该数据包所添加的序号就是15;
  3. 确认号字段——占 4 字节,是期望收到对方的下一个报文段的数据的第一个字节的序号。比如接收端收到由文件14个字节数据+TCP首部组成的数据包后,删除首部提取14个字节数据,返回的确认号为15,即告诉发送端下一次应该发送文件的第15个字节及其之后字节组成的数据包过来。
  4. 数据偏移(即首部长度)——占 4 位,它指出 TCP 报文段的数据起始处距离 TCP 报文段的起始处有多远,也就是TCP首部的长度。“数据偏移”的单位是 32 位字(以 4 字节为计算单位),最大1111表示15x4=60个字节,即表示TCP首部最大长度为60个字节,因此“选项”部分最多40个字节。
  5. 保留字段——占 6 位,保留为今后使用,但目前应置为 0。
  6. 这里的六位二进制位,分别表示不同含义:
    (1)紧急 URG —— 当 URG = 1 时,表明紧急指针字段有效。它告诉系统此报文段中有紧急数据,应尽快传送(相当于高优先级的数据)。 即URG=1的数据包不用排队直接优先传输。
    (2)同步 SYN —— 在TCP连接建立时用来同步序号,同步 SYN = 1 表示这是一个连接请求或连接接受报文。
    (3)确认 ACK —— 只有当 ACK = 1 时确认号字段才有效。当 ACK = 0 时,确认号无效。

(4)终止 FIN —— 用来释放TCP连接。
(5)推送 PSH —— 接收方的TCP收到该标志位为1的报文段会尽快上交应用进程,而不必等到接收缓存都填满再向上交付
(6)复位 RST —— 用来复位TCP连接。当RST=1时,表明TCP连接出现了异常,必须释放连接,然后再重新建立连接;RST置为1还用来拒绝一个非法的报文段或拒绝打开一个TCP连接

  1. 窗口字段 —— 占 2 字节,用来让对方设置发送窗口的依据,单位为字节。
  2. 检验和 —— 占 2 字节。检验和字段检验的范围包括首部和数据这两部分。在计算检验和时,要在 TCP 报文段的前面加上 12 字节的伪首部。
  3. 紧急指针字段 —— 占 16 位,指出在本报文段中紧急数据共有多少个字节(紧急数据放在本报文段数据的最前面)。
  4. 选项字段 —— 长度可变。TCP 最初只规定了一种选项,即最大报文段长度 MSS (Maximum Segment Size)是 TCP 报文段中的数据字段的最大长度。数据字段加上 TCP 首部才等于整个的 TCP 报文段。MSS 告诉对方 TCP:“我的缓存所能接收的报文段的数据字段的最大长度是 MSS 个字节。”其他选项有:窗口扩大选项、时间戳选项、选择确认选项(SACK)。
  5. 填充字段 —— 这是为了使整个首部长度是 4 字节的整数倍。

2. TCP 连接建立

2.1 三次握手过程

TCP 为什么是三次握手,而不是两次或四次?

TCP的连接建立要解决以下三个问题: ① 使TCP双方能够确知双方的存在(确认双方的发送和接收都是正常的) ② 使TCP双方能够协商一些参数(如最大窗口值、是否使用窗口扩大选项和时间戳选项以及服务质量等) ③ 使TCP双方能够对运输实体资源(如缓存大小、连接表中的项目等)进行分配

image.png

  1. 服务端进程准备好接收来自外部的 TCP 连接,服务端进程处于 LISTEN 状态,等待客户端连接请求。
  2. 客户端向服务器发出连接请求,请求中首部同步位 SYN = 1,同时选择一个初始序号 sequence ,简写 seq = x。SYN 报文段不允许携带数据,只消耗一个序号。此时,客户端进入 SYN-SEND 状态。
  3. 服务器收到客户端连接后,为该TCP连接分配缓存和变量,并需要确认客户端的报文段。在确认报文段中,把 SYN 和 ACK 位都置为 1 。确认号是 ack = x + 1,同时也为自己选择一个初始序号 seq = y。请注意,这个报文段也不能携带数据,但同样要消耗掉一个序号。此时,TCP 服务器进入 SYN-RECEIVED(同步收到) 状态。
  4. 客户端在收到服务器发出的响应后,还需要给出确认连接。确认连接中的 ACK 置为 1 ,序号为 seq = x + 1,确认号为 ack = y + 1。TCP 规定,这个报文段可以携带数据也可以不携带数据,如果不携带数据,那么下一个数据报文段的序号仍是 seq = x + 1(SYN会消耗一个序列号,ACK不会)。这时,客户端进入 ESTABLISHED (已连接) 状态
  5. 服务器收到客户的确认后,也进入 ESTABLISHED 状态。

2.2 为什么要三次握手

原因1:
三次握手的目的是建立可靠的通信信道,说到通讯,简单来说就是数据的发送与接收,而三次握手最主要的目的就是双方确认自己与对方的发送与接收是正常的

  • 第一次握手:Client 什么都不能确认;Server 确认了对方发送正常,自己接收正常
  • 第二次握手:Client 确认了:自己发送、接收正常,对方发送、接收正常;Server 确认了:对方发送正常,自己接收正常
  • 第三次握手:Client 确认了:自己发送、接收正常,对方发送、接收正常;Server 确认了:自己发送、接收正常,对方发送、接收正常

所以三次握手就能确认双方收发功能都正常,缺一不可。
原因2:
TCP可靠传输的精髓:TCP连接的一方A,由操作系统动态随机选取一个32位长的序列号(Initial+Sequence+Number),假设A的初始序列号为1000,以该序列号为原点,对自己将要发送的每个字节的数据进行编号,1001,1002,1003…,并把自己的初始序列号ISN告诉B,让B有一个思想准备,什么样编号的数据是合法的,什么编号是非法的,比如编号900就是非法的,同时B还可以对A每一个编号的字节数据进行确认。如果A收到B确认编号为2001,则意味着字节编号为1001-2000,共1000个字节已经安全到达。
同理B也是类似的操作,假设B的初始序列号ISN为2000,以该序列号为原点,对自己将要发送的每个字节的数据进行编号,2001,2002,2003…,并把自己的初始序列号ISN告诉A,以便A可以确认B发送的每一个字节。如果B收到A确认编号为4001,则意味着字节编号为2001-4000,共2000个字节已经安全到达。
一句话概括,TCP连接握手,握的是啥?通信双方数据原点的序列号!
如果是两次握手,会出现什么问题?
A与B就A的初始序列号达成了一致,这里是1000。但是B无法知道A是否已经接收到自己的同步信号,如果这个同步信号丢失了,A和B就B的初始序列号将无法达成一致。
于是TCP的设计者将SYN这个同步标志位SYN设计成占用一个字节的编号(FIN标志位也是),既然是一个字节的数据,按照TCP对有数据的TCP+segment+必须确认的原则,所以在这里A必须给B一个确认,以确认A已经接收到B的同步信号。
如果A发给B的确认丢了,该如何?A会超时重传这个ACK吗?不会!TCP不会为没有数据的ACK超时重传。那该如何是好?B如果没有收到A的ACK,会超时重传自己的SYN同步信号,一直到收到A的ACK为止。

  • 第一个包,即A发给B的SYN中途被丢,没有到达B

A会周期性超时重传,直到收到B的确认

  • 第二个包,即B发给A的SYNBACK中途被丢,没有到达A

B会周期性超时重传,直到收到A的确认

  • 第三个包,即A发给B的ACK中途被丢,没有到达B,A发完ACK,单方面认为TCP为Established状态,而B显然认为TCP为Active状态:

a. 假定此时双方都没有数据发送,B会周期性超时重传,直到收到A的确认,收到之后B的TCP连接也为Established状态,双向可以发包。 b. 假定此时A有数据发送,B收到A的Data+ACK,自然会切换为established状态,并接受A的Data。 c. 假定B有数据发送,数据发送不了,会一直周期性超时重传SYN+ACK,直到收到A的确认才可以发送数据。

2.3 第2次握手传回了ACK,为什么还要传回SYN?

接收端传回发送端所发送的ACK是为了告诉客户端,我接收到的信息确实就是你所发送的信号了,这表明从客户端到服务端的通信是正常的。而回传SYN则是为了建立并确认从服务端到客户端的通信

SYN 同步序列编号(Synchronize Sequence Numbers) 是 TCP/IP 建立连接时使用的握手信号。在客户机和服务器之间建立正常的 TCP 网络连接时,客户机首先发出一个 SYN 消息,服务器使用 SYN-ACK 应答表示接收到了这个消息,最后客户机再以 ACK(Acknowledgement)消息响应。这样在客户机和服务器之间才能建立起可靠的 TCP 连接,数据才可以在客户机和服务器之间传递。

2.4 为什么要有最后一次ACK(两次握手可以吗)

不可以。有两个原因:
首先,可能会出现已失效的连接请求报文段又传到了服务器端。(两次握手情况下,客户端收到一个SYN就会认为是一个新的连接,然后分配缓存和变量。但是实际上这个SYN报文可能并不是一个正常的连接请求报文,有可能是迟到的报文。这样服务端白白建立连接浪费资源。但是如果是三次握手,客户端不对服务端的ACK确认,服务端就会知道不需要建立连接了。)

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

计算机网络面试题 - 图16
其次,两次握手无法保证Client正确接收第二次握手的报文(Server无法确认Client是否收到),也无法保证Client和Server之间成功互换初始序列号。

2.5 四次握手可以吗

可以。但是会降低传输的效率。
四次握手是指:第二次握手:Server只发送ACK和acknowledge number;而Server的SYN和初始序列号在第三次握手时发送;原来协议中的第三次握手变为第四次握手。出于优化目的,四次握手中的二、三可以合并。

2.6 第三次握手中,如果客户端的ACK未送达服务器,会怎样?

Server端:

  • 由于Server没有收到ACK确认,因此会重发之前的SYN+ACK(默认重发五次,之后自动关闭连接进入CLOSED状态),Client收到后会重新传ACK给Server。

Client端,两种情况:

  • 在Server进行超时重发的过程中,如果Client向服务器发送数据,数据头部的ACK是为1的,所以服务器收到数据之后会读取 ACK number,进入 establish 状态
  • 在Server进入CLOSED状态之后,如果Client向服务器发送数据,服务器会以RST包应答。

2.7 如果已经建立了连接,但客户端出现了故障怎么办?

服务器每收到一次客户端的请求后都会重新复位一个计时器,时间通常是设置为2小时,若两小时还没有收到客户端的任何数据,服务器就会发送一个探测报文段,以后每隔75秒钟发送一次。若一连发送10个探测报文仍然没反应,服务器就认为客户端出了故障,接着就关闭连接。

2.8 SYN洪泛攻击

TCP SYN泛洪发生在OSI第四层,这种方式利用TCP协议的特性,就是三次握手。攻击者发送TCP SYN,SYN是TCP三次握手中的第一个数据包,而当服务器返回ACK后,该攻击者就不对其进行再确认,那这个TCP连接就处于挂起状态,也就是所谓的半连接状态,服务器收不到再确认的话,还会重复发送ACK给攻击者。这样更加会浪费服务器的资源。攻击者就对服务器发送非常大量的这种TCP连接,由于每一个都没法完成三次握手,所以在服务器上,这些TCP连接会因为挂起状态而消耗CPU和内存,最后服务器可能死机,就无法为正常用户提供服务了。

如何防御:
SYN cookie:

  • 当服务器收到SYN报文段时,他不知道该段是来自合法用户还是属于SYN泛洪攻击的一部分。因此,服务器不会为此SYN创建半开连接,而是创建初始TCP序列号,该序列号是由一个复杂的散列函数将 目标IP地址和SYN报文段中的端口号,以及只有该服务器知道的secret number,作为输入得到的。这个精心设计的初始序列号就是所谓的“cookie”。服务器然后向客户端发送带有这个特殊序列号的SYNACK报文段。重要的是服务器不用记住cookie或者与SYN相对应的任何状态和信息
    cookie = hash(src_ip, dest_ip, src_port, dest_port, secret_number) -> 初始序列号
  • 合法的客户端将返回ACK报文段。当服务器收到此ACK时,它必须验证ACK是否与之前发送的某些SYN相对应。但是服务器并没有记住SYN报文段,这怎么办?正如你可能已经猜到的那样,他是通过cookie完成的。回想一下,对于合法的ACK,确认字段中的值等于SYNACK中的初始序列号(本例中为cookie值)加一。然后,服务器可以使用ACK中的源和目标IP地址和端口号和secret number运行相同的散列函数。如果函数的结果加1与客户端的ACK中的确认字段的值相同,则服务器断定ACK段与之前的SYN段时相对应的,因此是有效的。然后服务器会创建一个完全打开的连接。
  • 另一方面,如果客户端没有返回ACK段,那么原始SYN没有对服务器造成任何伤害,因为服务器没有分配任何资源来响应原始的假SYN。

3. TCP 连接释放

3.1 四次挥手过程

image.png

  • 第一次挥手:Client将FIN置为1,发送一个序列号seq=u给Server;进入FIN_WAIT_1状态;
  • 第二次挥手:Server收到FIN之后,发送一个ACK=1,ack=u+1;进入CLOSE_WAIT状态。此时客户端已经没有要发送的数据了,但仍可以接受服务器发来的数据。
  • 第三次挥手:Server将FIN置1,发送一个序列号seq=w给Client;进入LAST_ACK状态;
  • 第四次挥手:Client收到服务器的FIN后,进入TIME_WAIT状态;接着将ACK置1,发送一个 ack=w+1 给服务器;服务器收到后,确认ack后,变为CLOSED状态,不再向客户端发送数据。客户端等待2*MSL(报文段最长寿命)时间后,也进入CLOSED状态。完成四次挥手。

3.2 为什么要四次挥手

TCP协议是一种 面向连接的、可靠的、基于字节流的 运输层通信协议。TCP是 全双工模式 ,这就意味着,当客户端发出FIN报文段时,只是表示客户端已经没有数据要发送了,客户端告诉服务器,它的数据已经全部发送完毕了;但是,这个时候客户端还是可以接受来自服务端的数据;当服务端返回ACK报文段时,表示它已经知道客户端没有数据发送了,但是服务端还是可以发送数据到客户端的;当服务端也发送了FIN报文段时,这个时候就表示服务端也没有数据要发送了,就会告诉客户端,我也没有数据要发送了,之后彼此就会愉快的中断这次TCP连接。
简单地说,前 2 次挥手用于关闭一个方向的数据通道,后两次挥手用于关闭另外一个方向的数据通道。

3.3 为什么不能把服务器发送的ACK和FIN合并起来,变成三次挥手(CLOSE_WAIT状态意义是什么)?

因为服务器收到客户端断开连接的请求时,可能还有一些数据没有发完,这时先回复ACK,表示接收到了断开连接的请求。等到数据发完之后再发FIN,断开服务器到客户端的数据传送。

3.4 为什么第四步要等待2MSL时间?TIME-WAIT

MSL是Maximum Segment Lifetime英文的缩写,中文可以译为“报文最大生存时间”,他是任何报文在网络上存在的最长时间,超过这个时间报文将被丢弃。 我认为之所以是2MSL而不是1MSL,是考虑客户端回复ACK和服务端重发FIN在网络中传递的最坏情况的用时,如果最坏用时都没收到重传的FIN,则认为正常断开连接。 除此之外,2MSL还可以确保本次连接中所以的报文都消失,不会影响下一次连接。 考虑这样两种特殊情况:

  • 客户端的ACK丢了,服务重传的FIN也丢了,客户端度过2MSL,关闭了连接,但是服务端还没关:这个时候客户端再接受到服务端的重传FIN就会认为这是一个错误,会回复RST报文,服务端收到后也会关闭连接
  • 客户端直接挂了,服务端重传的FIN始终没有得到响应。这个时候应该会在重传一定次数之后主动关闭

第四步客户端的确认报文如果丢失,那么服务端就会重传第三个报文段。客户端可以在2MSL时间段内收到重传的报文段,并重新启动2MSL计时器。这样可以确保关闭。
客户端发送第四个报文之后,启动计时器,等到2MSL。如果在这个时间内,第四个报文确认丢失,服务端会重传第三个报文,再次请求建立连接,这个时候客户端可以及时响应ACK,并重新启动计时器。如果2MSL时间内服务端没有重传第三个请求,说明客户端的ACK没有丢失,连接正常关闭了。这个时候计时器到时间了,客户端也进入CLOSED状态。

3.5 说一说你对TIME_WAIT的理解

  1. 出现 TIME_WAIT的状态原因
    TIME_WAIT状态之所以存在,是为了保证网络的可靠性。由于TCP连接是双向的,所以在关闭连接的时候,两个方向各自都需要关闭。先发FIN包的一方执行的是主动关闭,后发送FIN包的一方执行的是被动关闭。主动关闭的一方会进入TIME_WAIT状态,并且在此状态停留2MSL时长。如果Server端一直没有向client端发送FIN消息(调用close() API),那么这个CLOSE_WAIT会一直存在下去。
  2. MSL概念
    其指的是报文段的最大生存时间。如果报文段在网络中活动了MSL时间,还没有被接收,那么就会被丢弃。关于MSL的大小,RFC 793协议中给出的建议是2分钟,不过Linux中,通常是半分钟。
  3. TIME_WAIT持续两个MSL的作用
    首先,可靠安全地关闭TCP连接。比如网络拥塞,如果主动关闭方最后一个ACK没有被被动关闭方接收到,这时被动关闭方会对FIN进行超时重传,在这时尚未关闭的TIME_WAIT就会把这些尾巴问题处理掉,不至于对新连接及其他服务产生影响。其次,防止由于没有持续TIME_WAIT时间导致的新的TCP连接建立起来,延迟的FIN重传包会干扰新的连接。
  4. TIME_WAIT占用的资源
    少量内存(大概4K)和一个文件描述符fd。
  5. TIME_WAIT关闭的危害
    1. 首先,当网络情况不好时,如果主动方无TIME_WAIT等待,关闭前个连接后,主动方与被动方又建立起新的TCP连接,这时被动方重传或延时过来的FIN包到达后会直接影响新的TCP连接;
    2. 其次,当网络情况不好时,同时没有TIME_WAIT等待时,关闭连接后无新连接,那么当接收到被动方重传或延迟的FIN包后,会给被动方回送一个RST包,可能会影响被动方其他的服务连接。

3.6 有大量的TIME_WAIT状态怎么办

(1) 客户端 :HTTP 请求的头部,connection 设置为 keep-alive,保持存活一段时间:现在的浏览器,一般都这么进行了 。
(2) 服务器端
a. 允许 time_wait状态的 socket 被 重用
b. 缩减 time_wait 时间,设置为 1 MSL(即,2 mins)

4. TCP 协议如何保证可靠传输

可靠:保证接收方进程从缓存区读出的字节流和发送方发出的字节流是完全一样的。

  1. 应用数据被分割成 TCP 认为最适合发送的数据块。
  2. 序号:TCP 给发送的每一个字节进行编号,并且在首部的序号字段注明本报文段所发送的数据的第一个字节的序号,接收方对数据包进行排序,把有序数据传送给应用层。
  3. 确认:接收方接收到发送方发送的报文后回复ACK确认。发送方发送完数据之后不会立即将数据从缓存中删除,因为发送的数据有可能在发送过程中丢失了,需要重传。直到发送方收到了接收方的确认之后,才会真正删除它。所以确认机制可以告诉发送方应该重传哪个报文段。
  4. 自动重传:确认重传不分家,TCP在发送方规定的时间内没有收到确认就要重传已发送的报文段(超时重传)。通过ARQ协议实现,分为停止等待ARQ(超时重传)和连续ARQ(累积确认)。基本原理是在发送方在不能及时收到确认的情况下,重发报文段。
  5. 校验和: TCP 将保持它首部和数据的检验和。这是一个端到端的检验和,目的是检测数据在传输过程中的任何变化。如果收到段的检验和有差错,TCP 将丢弃这个报文段和不确认收到此报文段。
  6. TCP 的接收端会丢弃重复的数据。
  7. 流量控制: TCP 连接的每一方都有固定大小的缓冲空间,TCP的接收端只允许发送端发送接收端缓冲区能接纳的数据。当接收方来不及处理发送方的数据,能提示发送方降低发送的速率,防止包丢失。TCP 使用的流量控制协议是可变大小的滑动窗口协议。 (TCP 利用滑动窗口实现流量控制)
  8. 拥塞控制: 当网络拥塞时,减少数据的发送。

4.1 ARQ协议

自动重传请求(Automatic Repeat-reQuest,ARQ)是OSI模型中数据链路层和传输层的错误纠正协议之一。它通过使用确认和超时这两个机制,在不可靠服务的基础上实现可靠的信息传输。如果发送方在发送后一段时间之内没有收到确认帧,它通常会重新发送。ARQ包括停止等待ARQ协议和连续ARQ协议。

1. 停止等待ARQ协议
停止等待协议是为了实现可靠传输的,它的基本原理就是每发完一个分组就停止发送,等待对方确认(回复ACK)。如果过了一段时间(超时时间后),还是没有收到 ACK 确认,说明没有发送成功,需要重新发送,直到收到确认后再发下一个分组。
在停止等待协议中,若接收方收到重复分组,就丢弃该分组,但同时还要发送确认。
优缺点:

  • 优点: 简单
  • 缺点: 信道利用率低,等待时间长

1) 无差错情况:
发送方发送分组,接收方在规定时间内收到,并且回复确认.发送方再次发送。
2) 出现差错情况(超时重传):
停止等待协议中超时重传是指只要超过一段时间仍然没有收到确认,就重传前面发送过的分组(认为刚才发送过的分组丢失了)。因此每发送完一个分组需要设置一个超时计时器,其重传时间应比数据在分组传输的平均往返时间更长一些。这种自动重传方式常称为 自动重传请求 ARQ 。另外在停止等待协议中若收到重复分组,就丢弃该分组,但同时还要发送确认。
3) 确认丢失和确认迟到

  • 确认 丢失 :确认消息(ACK)在传输过程丢失。当A发送M1消息,B收到后,B向A发送了一个M1确认消息,但却在传输过程中丢失。而A并不知道,在超时计时过后,A重传M1消息,B再次收到该消息后采取以下两点措施:1. 丢弃这个重复的M1消息,不向上层交付。 2. 向A发送确认消息。(不会认为已经发送过了,就不再发送。A能重传,就证明B的确认消息丢失)。
  • 确认 迟到 :确认消息(ACK)在传输过程中迟到。A发送M1消息,B收到并发送确认。在超时时间内没有收到确认消息,A重传M1消息,B仍然收到并继续发送确认消息(B收到了2份M1)。此时A收到了B第二次发送的确认消息。接着发送其他数据。过了一会,A收到了B第一次发送的对M1的确认消息(A也收到了2份确认消息)。处理如下:1. A收到重复的确认后,直接丢弃。2. B收到重复的M1后,也直接丢弃重复的M1。

2. 连续ARQ协议
连续 ARQ 协议可提高信道利用率。发送方维持一个发送窗口,凡位于发送窗口内的分组可以连续发送出去,而不需要等待对方确认。接收方一般采用累计确认,对按序到达的最后一个分组发送确认,表明到这个分组为止的所有分组都已经正确收到了。
优缺点:

  • 优点: 信道利用率高,容易实现,即使确认丢失,也不必重传。
  • 缺点: 不能向发送方反映出接收方已经正确收到的所有分组的信息。 比如:发送方发送了 5条 消息,中间第三条丢失(3号),这时接收方只能对前两个发送确认。发送方无法知道后三个分组的下落,而只好把后三个全部重传一次。这也叫 Go-Back-N(回退 N),表示需要退回来重传已经发送过的 N 个消息。

4.2 滑动窗口和流量控制

  • TCP 利用滑动窗口实现流量控制。流量控制是为了控制发送方发送速率,保证接收方来得及接收。
  • 接收方发送的确认报文中的窗口字段可以用来控制发送方窗口大小,从而影响发送方的发送速率。将窗口字段设置为 0,则发送方不能发送数据。
  • 考虑一种特殊的情况,就是接收方若没有足够缓存使用,就会发送零窗口大小的报文,此时发送方将发送窗口设置为0,停止发送数据。之后接收方有足够的缓存,发送了非零窗口大小的报文,但是这个报文在中途丢失了,那么发送方的发送窗口就一直为零导致死锁。解决这个问题,TCP为每一个连接设置一个持续计时器(persistence timer)。只要TCP的一方收到对方的零窗口通知,就启动该计时器,周期性的发送一个零窗口探测报文段。对方就在确认这个报文的时候给出现在的窗口大小(注意:TCP规定,即使设置为零窗口,也必须接收以下几种报文段:零窗口探测报文段、确认报文段和携带紧急数据的报文段)。
  1. TCP的滑动窗口
    为了提高信道的利用率TCP协议不使用停止等待协议,而是使用连续ARQ协议,意思就是可以连续发出若干个分组然后等待确认,而不是发送一个分组就停止并等待该分组的确认。
    TCP的两端都有发送/接收缓存和发送/接收窗口。TCP的缓存是一个循环队列,其中发送窗口可以用3个指针表示。而发送窗口的大小受TCP数据报中窗口大小的影响,TCP数据报中的窗口大小是接收端通知发送端其还可以接收多少数据,所以发送窗口根据接收的的窗口大小的值动态变化。
    以下的几张图片就帮助理解一下滑动窗口的机制:

滑动窗口1.PNG

图1 根据B给出的窗口值,A构造出自己的发送窗口(20)

滑动窗口2.PNG

  1. 2 A发送了11个字节的数据<br /> 注意上图中的3个指针P1P2P3!此时接收窗口中接收的数据可能是失序的,但是也先存储在接收缓存之中。发送确认号的时候依然发送31,表示B期望接收的下一个数据报的标示符是31

滑动窗口3.PNG


图3 A收到新的确认号,发送窗口向前滑动。P1由31移动到34,表示34之前已经全部收到。P2由51移动到54,维持窗口大小。

滑动窗口4.PNG


图4 发送窗口内的序号都属于已经发送但未被确认
如果发送窗口中的数据报都属于已发送但未被确认的话,那么A就不能再继续发送数据,而需要进行等待。

滑动窗口5.PNG

图5 TCP的发送缓存和发送窗口(a)与接收缓存和接收窗口(b)

image.png

  1. 传输效率及Nagle算法
    TCP的数据传输分为交互数据流和成块数据流,交互数据流一般是一些交互式应用程序的命令,所以这些数据很小,而考虑到TCP报头和IP报头的总和就有40字节,如果数据量很小的话,那么网络的利用效率就较低。
    数据传输使用Nagle算法,Nagle算法很简单,就是规定一个TCP连接最多只能有一个未被确认的未完成的小分组。在该分组的确认到达之前不能发送其他的小分组。
    但是也要考虑另一个问题,叫做糊涂窗口综合症。当接收方的缓存已满的时候,交互应用程序一次只从缓存中读取一个字节(这时候缓存中腾出一个字节),然后向发送方发送确认信息,此时发送方再发送一个字节(收到的窗口大小为1),这样网络的效率很低。
    要解决这个问题,可以让接收方等待一段时间,使得接收缓存已有最够的空间容纳一个最长报文段,或者等到接收缓存已有一半的空间。只要这两种情况出现一种,就发送确认报文,同时发送方可以把数据积累成大的报文段发送。

4.3 拥塞控制

  • 在某段时间,若对网络中某一资源的需求超过了该资源所能提供的可用部分,网络的性能就要变坏。这种情况就叫拥塞。(计算机网络中的链路容量(带宽)、交换节点中的缓存和处理机等,都是网络的资源)
  • 拥塞控制就是为了防止过多的数据注入到网络中,这样就可以使网络中的路由器或链路不致过载。

与流量控制的区别:

  • 流量控制是 端到端 的控制,例如A通过网络给B发数据,A发送的太快导致B没法接收(B缓冲窗口过小或者处理过慢),这时候的控制就是流量控制,原理是通过滑动窗口的大小改变来实现。
  • 拥塞控制是A与B之间的网络发生堵塞导致传输过慢或者丢包,来不及传输。防止过多的数据注入到网络中,这样可以使网络中的路由器或链路不至于过载。拥塞控制是一个 全局性 的过程,涉及到所有的主机、路由器,以及与降低网络性能有关的所有因素。

为了进行拥塞控制,TCP 发送方要维持一个 拥塞窗口(cwnd) 的状态变量。拥塞控制窗口的大小取决于网络的拥塞程度,并且动态变化。发送方让自己的发送窗口取为拥塞窗口和接收方的接受窗口中较小的一个。

  • 接收窗口:接收方根据接收缓存设置的值,并告知发送方,反映接收方容量。
  • 拥塞窗口:发送方根据自己估算的网络拥塞而设置的窗口值,反映网络当前容量。
  • 拥塞窗口cwnd的维护原则:只要网络没有出现拥塞,拥塞窗口就再增大一些;只要网络出现拥塞,拥塞窗口就减少一些。
  • 判断网络出现拥塞的依据:没有按时收到应该到达的确认报文(即发生超时重传)

TCP的拥塞控制采用了四种算法,即 慢开始拥塞避免快重传快恢复。在网络层也可以使路由器采用适当的分组丢弃策略(如主动队列管理 AQM),以减少网络拥塞的发生。

  • 慢开始与拥塞避免: 慢开始算法的思路是当主机开始发送数据时,如果立即把大量数据字节注入到网络,那么可能会引起网络阻塞,因为现在还不知道网络的负荷情况。经验表明,较好的方法是先探测一下,即由小到大逐渐增大发送窗口,也就是由小到大逐渐增大拥塞窗口数值。cwnd初始值为1,每经过一个传播轮次(发送了一批报文段并收到了他们的确认的时间),cwnd加倍(指数级增长)。当拥塞窗口>=慢开始阈值(ssthresh)时,进入拥塞避免,避免增长过快导致网络拥塞。拥塞避免算法的思路是让拥塞窗口cwnd缓慢增大,即每经过一个往返时间RTT就把发送方的cwnd加1(加法增长).当增长到一定程度,网络出现了拥塞(重传计时器超时,则判断网络很可能出现了拥塞),则将拥塞窗口大小直接降为1,并将新的慢开始门限设为网络出现拥塞时的窗口的一半。

image.png

  • 有时,个别报文段会在网络中丢失,但实际上网络并没有发生拥塞。这将导致发送方超时重传,并误认为网络发生了拥塞,发送方把拥塞窗口cwnd又设置为最小值1,并错误地启动慢开始算法,因而降低了传输效率。
  • 快重传:所谓快重传就是使发送方尽快进行重传,而不是等超时重传计时器超时再重传(重传计数器超时的话就要执行慢开始了,避免动不动就慢开始了)
    • 要求接收方不要等待自己发送数据时才进行捎带确认,而是要立即发送确认
    • 即使收到了失序的报文段也要立即发出对已收到的报文段的重复确认
    • 发送方一旦收到3个连续的重复确认(冗余ACK),就将相应的报文段立即重传,而不是等该报文段的超时重传计时器超时再重传。如下图所示,没有等到RTO就进行了重传,缩短了重传时间。
    • 对于个别丢失的报文段,发送方不会出现超时重传,也就不会误认为出现了拥塞(进而降低拥塞窗口cwnd为1)。使用快重传可以使整个网络的吞吐量提高越20%。

image.png

  • 快恢复: 发送方一旦收到3个重复确认,就知道现在只是丢失了个别的报文段。于是不启动慢开始算法,而是执行快恢复算法,将慢开始门限和拥塞窗口值调整为当前窗口的一半(而不是直接降到1),然后开始执行拥塞避免算法。
    • 既然发送方收到3个重复的确认,就表明有3个数据报文段已经离开了网络
    • 这三个报文段不再消耗网络资源而是停留在接收方的接收缓存中
    • 可见现在网络中不是堆积了报文段而是减少了3个报文段,因此可以适当把拥塞窗口扩大些

计算机网络面试题 - 图26

5. TCP和UDP 协议的区别

  1. 连接:TCP是面向连接的传输层协议,即传输数据之前必须先建立好连接;UDP无连接。
  2. 服务对象:TCP点对点的两点间服务,即一条TCP连接只能有两个端点;UDP支持一对一,一对多,多对一,多对多的交互通信。
  3. 可靠性:TCP可靠交付:无差错,不丢失,不重复,按序到达;UDP尽最大努力交付,不保证可靠交付。
  4. 拥塞控制/流量控制:有拥塞控制和流量控制保证数据传输的安全性;UDP没有拥塞控制,网络拥塞不会影响源主机的发送效率。
  5. 报文长度:TCP动态报文长度,即TCP报文长度是根据接收方的窗口大小和当前网络拥塞情况决定的;UDP面向报文,不合并,不拆分,保留上面传下来报文的边界。
  6. 首部开销:TCP首部开销大,首部20个字节;UDP首部开销小,8字节(源端口,目的端口,数据长度,校验和)。
  7. 适用场景(由特性决定):数据完整性需让位于通信实时性,则应该选用TCP 协议(如文件传输、重要状态的更新等);反之,则使用 UDP 协议(如视频传输、实时通信等)。
  8. TCP面向字节流;UDP面向应用报文,对应用层交付的报文直接打包。

6. TCP和UDP对于网络稳定性有什么要求?

  1. TCP优缺点
    优点:可靠、稳定
    TCP的可靠体现在TCP在传输数据之前,会有三次握手来建立连接,而且在数据传递时,有确认、窗口、重传、拥塞控制机制,在数据传完之后,还会断开连接用来节约系统资源。
    缺点:慢,效率低,占用系统资源高,易被攻击
    在传递数据之前要先建立连接,这会消耗时间,而且在数据传递时,确认机制、重传机制、拥塞机制等都会消耗大量时间,而且要在每台设备上维护所有的传输连接。然而,每个链接都会占用系统的CPU、内存等硬件资源。因为TCP有确认机制、三次握手机制,这些也导致TCP容易被利用,实现DOS、DDOS、CC等攻击。
  2. UDP优缺点
    优点:快,比TCP稍安全
    UDP没有TCP拥有的各种机制,是一个无状态的传输协议,所以传递数据非常快,没有TCP的这些机制,被攻击利用的机制就少一些,但是也无法避免被攻击。
    缺点:不可靠,不稳定
    因为没有TCP的那些机制,UDP在传输数据时,如果网络质量不好,就会很容易丢包,造成数据的缺失。
  3. 适用场景(网络稳定性要求
    TCP:当对网络通讯质量有要求时,比如HTTP、HTTPS、FTP等传输文件的协议, POP、SMTP等邮件传输的协议
    UDP:对网络通讯质量要求不高时,要求网络通讯速度要快的场景。
    所以,TCP对网络稳定性要求高,而UDP相对弱一些。

7. 如何让UDP可靠一些?

  1. 为什么需要可靠的UDP
    在弱网(2G、3G、信号不好)环境下,使用 TCP 连接的延迟很高,影响体验。使用 UDP 是很好的解决方案,既然把 UDP 作为弱网里面的 TCP 来使用,就必须保证数据传输能像 TCP 一样可靠
  2. 如何实现可靠的UDP
    UDP它不属于连接型协议,因而具有资源消耗小,处理速度快的优点,所以通常音频、视频和普通数据在传送时使用UDP较多,因为它们即使偶尔丢失一两个数据包,也不会对接收结果产生太大影响。传输层无法保证数据的可靠传输,只能通过应用层来实现了。实现的方式可以参照tcp可靠性传输的方式,只是实现不在传输层,实现转移到了应用层。关键在于两点,从应用层角度考虑:
    (1)提供超时重传,能避免数据报丢失。
    (2)提供确认序列号,可以对数据报进行确认和排序。
    本端:首先在UDP数据报定义一个首部,首部包含确认序列号和时间戳,时间戳是用来计算RTT(数据报传输的往返时间),计算出合适的RTO(重传的超时时间)。然后以等-停的方式发送数据报,即收到对端的确认之后才发送下一个的数据报。当时间超时,本端重传数据报,同时RTO扩大为原来的两倍,重新开始计时。
    对端:接受到一个数据报之后取下该数据报首部的时间戳和确认序列号,并添加本端的确认数据报首部之后发送给对端。根据此序列号对已收到的数据报进行排序并丢弃重复的数据报。

扩展资料

  1. 已经实现的可靠UDP:

(1)RUDP 可靠数据报传输协议;
(2)RTP 实时传输协议
为数据提供了具有实时特征的端对端传送服务;
Eg:组播或单播网络服务下的交互式视频、音频或模拟数据
(3)UDT
基于UDP的数据传输协议,是一种互联网传输协议;
主要目的是支持高速广域网上的海量数据传输,引入了新的拥塞控制和数据可靠性控制机制(互联网上的标准数据传输协议TCP在高带宽长距离的网络上性能很差);
UDT是面向连接的双向的应用层协议,同时支持可靠的数据流传输和部分可靠的数据报服务;
应用:高速数据传输,点到点技术(P2P),防火墙穿透,多媒体数据传输;

8. 介绍一下tcp粘包、拆包的机制

8.1. TCP粘包和拆包问题

TCP是一个“流”协议,所谓流,就是没有界限的一长串二进制数据。TCP作为传输层协议并不了解上层业务数据的具体含义,它会根据TCP缓冲区的实际情况进行数据包的划分,所以在业务上认为是一个完整的包,可能会被TCP拆分成多个包进行发送,也有可能把多个小的包封装成一个大的数据包发送,这就是所谓的TCP拆包和粘包问题。

8.2 产生TCP粘包和拆包的原因

我们知道TCP是以流动的方式传输数据的,传输的最小单位为一个报文段(Segment)。TCP Header中有个Options标识位。常见的标识位为MSS(Maximum Segment Size)指的是,连接层每次传输的数据有个最大限制MTU(Maximum Transmission Unit),一般是1500bit,超过这个量要分成多个报文段,MSS则是这个最大限制减去TCP的header,光是要传输的数据的大小,一般为1460bit。换算成字节,也就是180多字节。
TCP为提高性能,发送端会将需要发送的数据发送到缓冲区,等待缓冲区满了以后,再将缓冲中的数据发送到接收方。同理,接收方也有缓冲区这样的机制来接受数据。
发生TCP粘包、拆包主要是以下原因:
(1)应用程序写入数据大于套接字缓冲区大小,会发生拆包;
(2)应用程序写入数据小于套接字缓冲区大小,网卡将应用多次写入的数据发送到网络上,这将会发送粘包;
(3)进行MSS(最大报文长度)大小的TCP分段,当TCP报文长度-TCP header长度>MSS 的时候会发生拆包;
(4)接收方法不及时读取套接字缓冲区数据,这将发生粘包。

8.3 如何处理粘包和拆包

假设应用层协议是http,我从浏览器中访问了一个网站,网站服务器给我发了200k的数据。建立连接的时候,通告的MSS是50k,所以为了防止ip层分片,tcp每次只会发送50k的数据,一共发了4个tcp数据包。如果我又访问了另一个网站,这个网站给我发了100k的数据,这次tcp会发出2个包,问题是,客户端收到6个包,怎么知道前4个包是一个页面,后两个是一个页面。既然是tcp将这些包分开了,那tcp会将这些包重组吗,它送给应用层的是什么?这是我自己想的一个场景,正式一点讲的话,这个现象叫拆包

我们再考虑一个问题。tcp中有一个negal算法,用途是这样的:通信两端有很多小的数据包要发送,虽然传送的数据很少,但是流程一点没少,也需要tcp的各种确认,校验。这样小的数据包如果很多,会造成网络资源很大的浪费,negal算法做了这样一件事,当来了一个很小的数据包,我不急于发送这个包,而是等来了更多的包,将这些小包组合成大包之后一并发送,不就提高了网络传输的效率的嘛。这个想法收到了很好的效果,但是我们想一下,如果是分属于两个不同页面的包,被合并在了一起,那客户那边如何区分它们呢这就是粘包问题。
从粘包问题我们更可以看出为什么tcp被称为流协议,因为它就跟水流一样,是没有边界的,没有消息的边界保护机制,所以tcp只有流的概念,没有包的概念
我们还需要有两个概念:
(1)长连接:Client方与Server方先建立通讯连接,连接建立后不断开, 然后再进行报文发送和接收。
(2)短连接:Client方与Server每进行一次报文收发交易时才进行通讯连接,交易完毕后立即断开连接。此种方式常用于一点对多点 通讯,比如多个Client连接一个Server。
实际,我想象的关于粘包的场景是不对的,http连接是短连接,请求之后,收到回答,立马断开连接,不会出现粘包。拆包现象是有可能存在的。

处理拆包这里提供两种方法:
(1)通过包头+包长+包体的协议形式,当服务器端获取到指定的包长时才说明获取完整。
(2)指定包的结束标识,这样当我们获取到指定的标识时,说明包获取完整。

处理粘包我们从上面的分析看到,虽然像http这样的短连接协议不会出现粘包的现象,但是一旦建立了长连接,粘包还是有可能会发生的。处理粘包的方法如下:
(1)发送方对于发送方造成的粘包问题,可以通过关闭Nagle算法来解决,使用TCP_NODELAY选项来关闭算法。
(2)接收方没有办法来处理粘包现象,只能将问题交给应用层来处理。应用层的解决办法简单可行,不仅能解决接收方的粘包问题,还可以解决发送方的粘包问题。解决办法:循环处理,应用程序从接收缓存中读取分组时,读完一条数据,就应该循环读取下一条数据,直到所有数据都被处理完成,判断每条数据的长度的方法有两种:
a. 格式化数据:每条数据有固定的格式(开始符,结束符),这种方法简单易行,但是选择开始符和结束符时一定要确保每条数据的内部不包含开始符和结束符(可以转义)。
b. 发送长度:发送每条数据时,将数据的长度一并发送,例如规定数据的前4位是数据的长度,应用层在处理时可以根据长度来判断每个分组的开始和结束位置。

8.5 UDP会不会产生粘包问题呢?

TCP为了保证可靠传输并减少额外的开销(每次发包都要验证),采用了基于流的传输,基于流的传输不认为消息是一条一条的,是无保护消息边界的(保护消息边界:指传输协议把数据当做一条独立的消息在网上传输,接收端一次只能接受一条独立的消息)。UDP则是面向消息传输的,是有保护消息边界的,接收方一次只接受一条独立的信息,所以不存在粘包问题。
举个例子:有三个数据包,大小分别为2k、4k、6k,如果采用UDP发送的话,不管接受方的接收缓存有多大,我们必须要进行至少三次以上的发送才能把数据包发送完,但是使用TCP协议发送的话,我们只需要接受方的接收缓存有12k的大小,就可以一次把这3个数据包全部发送完毕。

9. 说一说TCP里的reset状态。

  1. TCP异常终止(reset报文)
    TCP的异常终止是相对于正常释放TCP连接的过程而言的,我们都知道,TCP连接的建立是通过三次握手完成的,而TCP正常释放连接是通过四次挥手来完成,但是有些情况下,TCP在交互的过程中会出现一些意想不到的情况,导致TCP无法按照正常的四次挥手来释放连接,如果此时不通过其他的方式来释放TCP连接的话,这个TCP连接将会一直存在,占用系统的部分资源。在这种情况下,我们就需要有一种能够释放TCP连接的机制,这种机制就是TCP的reset报文。reset报文是指TCP报头的标志字段中的reset位置1的报文。
  2. RST标志位(Reset)
    RST表示复位,用来异常地关闭连接,在TCP的设计中它是不可或缺的。就像上面说的一样,发送RST包关闭连接时,不必等缓冲区的包都发出去(不像上面的FIN包),直接就丢弃缓存区的包发送RST包。而接收端收到RST包后,也不必发送ACK包来确认。
    TCP处理程序会在自己认为的异常时刻发送RST包。例如,A向B发起连接,但B之上并未监听相应的端口,这时B操作系统上的TCP处理程序会发RST包。
    又比如,AB正常建立连接了,正在通讯时,A向B发送了FIN包要求关连接,B发送ACK后,网断了,A通过若干原因放弃了这个连接(例如进程重启)。网通了后,B又开始发数据包,A收到后表示压力很大,不知道这野连接哪来的,就发了个RST包强制把连接关了,B收到后会出现connect reset by peer错误。

TCP异常终止的常见情形
(1)客户端尝试与服务器未对外提供服务的端口建立TCP连接,服务器将会直接向客户端发送reset报文。
(2)客户端和服务器的某一方在交互的过程中发生异常(如程序崩溃等),该方系统将向对端发送TCP reset报文,告之对方释放相关的TCP连接。
(3)接收端收到TCP报文,但是发现该TCP的报文,并不在其已建立的TCP连接列表内,则其直接向对端发送reset报文。
(4)在交互的双方中的某一方长期未收到来自对方的确认报文,则其在超出一定的重传次数或时间后,会主动向对端发送reset报文释放该TCP连接。
(5)有些应用开发者在设计应用系统时,会利用reset报文快速释放已经完成数据交互的TCP连接,以提高业务交互的效率。

四、应用层

1. 在浏览器中输入url地址到显示主页的过程

总体来说分为以下几个过程:

  1. DNS解析:浏览器查询 DNS,获取域名对应的IP地址:具体过程包括浏览器搜索自身的DNS缓存、搜索操作系统的DNS缓存、读取本地的Host文件和向本地DNS服务器进行查询等。对于向本地DNS服务器进行查询,如果要查询的域名包含在本地配置区域资源中,则返回解析结果给客户机,完成域名解析(此解析具有权威性);如果要查询的域名不由本地DNS服务器区域解析,但该服务器已缓存了此网址映射关系,则调用这个IP地址映射,完成域名解析(此解析不具有权威性)。如果本地域名服务器并未缓存该网址映射关系,那么将根据其设置发起递归查询或者迭代查询;
  2. TCP连接:浏览器获得域名对应的IP地址以后,浏览器向服务器请求建立链接,发起三次握手;
  3. 发送HTTP请求:TCP/IP链接建立起来后,浏览器向服务器发送HTTP请求;
  4. 服务器处理请求并返回HTTP报文:服务器接收到这个请求,并根据路径参数映射到特定的请求处理器进行处理,并将处理结果及相应的视图返回给浏览器;
  5. 浏览器解析渲染页面:浏览器解析并渲染视图,若遇到对js文件、css文件及图片等静态资源的引用,则重复上述步骤并向服务器请求这些资源;
  6. 连接结束:浏览器根据其请求到的资源、数据渲染页面,最终向用户呈现一个完整的页面。

具体可以参考下面这篇文章:

2. 了解网络编程协议吗?客户端发送给服务器的请求,怎么确定具体的协议?

了解,客户端发送给服务器端的请求,可以根据统一资源定位系统(uniform resource locator,URL)来确定具体使用的协议。
一个完整的URL包括–协议部分、网址、文件地址部分。协议部分以//为分隔符,在interner中,我们可以使用多种协议:
HTTP——HyperText Transfer Protocol(超文本传输协议)
FTP——File Transfer Protocol(文件传输协议)
Gopher——The Internet Gopher Protocol(网际Gopher协议)
File——本地文件传输协议
HTTPS——安全套接字层超文本传输协议(http的安全版)
例如牛客网址:http://nowcoder.com,可以看出使用的是http协议。

3. 应用层报文怎么传输到另一个应用层

应用层数据(报文)向外发送时,数据是由最上面的应用层向下经过一层层封装后发送给物理层;而接收数据时,数据是由物理层向上经过一层层解封后发给应用层。数据的封装和解封过程如下:

  1. 数据的封装过程简介
    传输层及其以下的机制由内核提供, 应用层由用户进程提供, 应用程序对通讯数据的含义进行解释, 而传输层及其以下处理通讯的细节,将数据从一台计算机通过一定的路径发送到另一台计算机。 应用层数据通过协议栈发到网络上时,每层协议都要加上一个相对应的头部(header ),该过程称为封装封装过程如下图所示:
    封装过程.png
  2. 数据的解封过程简介
    不同的协议层对数据包有不同的称谓,在传输层叫做段(segment ),在网络层叫做数据报( datagram) ,在链路层叫做帧(frame )。数据封装成帧后发到传输介质上,到达目的主机后,每层协议再剥掉相应的头部,最后将应用层数据交给应用程序处理,该过程称为解封。解封过程如下图所示:

解封过程.png

  1. 举例说明数据封装和解封装过程
    (1)从计算机 A 的应用层内网通软件向计算机 B 发出一个消息,生成数据;
    (2)请求从计算机 A 的应用层下到 计算机A 的传输层,传输层在上层数据前面加上 TCP报头,报头中包括目标端口以及源端口;
    (3)传输层数据下到网络层,计算机A 在网络层封装,源 IP地址为 计算机A地址,目标 IP地址为 计算机 B 地址;
    (4)计算机 A 将计算机B 的 IP 地址和子网掩码与自己做比对,可以发现 计算机 B 与自己处于相同的子网。所以数据传输不必经过网关设备;
    (5)数据包下到 计算机 A 的数据链路层进行封装,源 MAC 地址为 计算机A的 MAC地址,目标 MAC 地址查询自己的 ARP 表。
    (6)计算机 A 把帧转换成 bit 流,从物理接口网卡发出;
    (7)物理层接收到电信号,把它交给数据链路层进行查看帧的目标 MAC 地址,和自己是否相等,如果相等说明该帧是发送给自己的,于是将MAC帧头解开并接着上传到网络层;
    (8)网络层查看目标 IP 地址和自己是否匹配,如果匹配即解开 IP 头封装。然后再把数据上传到传输层;
    (9)传输层解开对应的包头之后,继续把数据传给应用层,计算机 B 即可接收到计算机 A 发的消息。

4. 域名系统DNS

万字长文爆肝 DNS 协议!

4.1 什么是DNS协议

DNS就是域名系统,是因特网中的一项核心服务,是用于实现域名和IP地址相互映射的一个分布式数据库,能够使用户更方便的访问互联网,而不用去记住能够被机器直接读取的IP数串。通过主机名,得到该主机名对应的IP地址的过程叫做域名解析(或主机名解析)。

4.2 DNS在域名解析上用的UDP还是TCP

  • 域名解析使用的是UDP协议

因为UDP快啊!UDP的DNS协议只要一个请求、一个应答就好了。而使用基于TCP的DNS协议要三次握手、发送数据以及应答、四次挥手。但是UDP协议传输内容不能超过512字节。不过客户端向DNS服务器查询域名,一般返回的内容都不超过512字节,用UDP传输即可。

  • 区域传送使用TCP协议

    DNS的规范规定了2种类型的DNS服务器,一个叫主DNS服务器,一个叫辅助DNS服务器。在一个区中主DNS服务器从自己本机的数据文件中读取该区的DNS数据信息,而辅助DNS服务器则从区的主DNS服务器中读取该区的DNS数据信息。当一个辅助DNS服务器启动时,它需要与主DNS服务器通信,并加载数据信息,这就叫做区传送(zone transfer)。

因为TCP协议可靠性好啊!你要从主DNS上复制内容啊,你用不可靠的UDP? 因为TCP协议传输的内容大啊,你用最大只能传512字节的UDP协议?万一同步的数据大于512字节,你怎么办?

4.3 域名

计算机网络面试题 - 图29
计算机网络面试题 - 图30
计算机网络面试题 - 图31

4.4 域名服务器

  • 域名和IP地址的映射关系必须保存在域名服务器中,供所有其他应用查询。显然不能将所有信息都储存在一台域名服务器中。 DNS使用分布在世界各地的域名服务器来实现域名到IP地址的转换。
  • 域名服务器可以划分为以下四种不同的类型:
    • 根域名服务器

根域名服务器是最高层次的域名服务器。每个根域名服务器都知道所有的顶级域名服务器的域名及其IP地址。因特网上共有13个不同IP地址的根域名服务器。尽管我们将这13个根域名服务器中的每一个都视为单个的服务器,但“每台服务器”实际上是由许多分布在世界各地的计算机构成的服务器群集。当本地域名服务器向根域名服务器发出查询请求时,路由器就把查询请求报文转发到离这个DNS客户最近的一个根域名服务器。这就加快了DNS的查询过程,同时也更合理地利用了因特网的资源。根域名服务器通常并不直接对域名迸行解析,而是返回该域名所属顶级域名的顶级域名服务器的IP地址。

  • 顶级域名服务器

    这些域名服务器负责管理在该顶级域名服务器注册的所有二级域名。当收到DNS查询请求时就给出相应的回答(可能是最后的结果,也可能是下一级权限域名服务器的IP地址).

  • 权限域名服务器

这些域名服务器负责管理某个区的域名。每一个主机的域名都必须在某个权限域名服务器处注册登记。因此权限域名服务器知道其管辖的域名与IP地址的映射关系。另外,权限域名服务器还知道其下级域名服务器的地址。

  • 本地域名服务器

本地域名服务器不属于上述的域名服务器的等级结构。当一个主机发出DNS请求报文时,这个报文就首先被送往该主机的本地域名服务器。本地域名服务器起着代理的作用,会将该报文转发到上述的域名服务器的等级结构中,每一个因特网服务提供者ISP, 一个大学,甚至一个大学里的学院,都可以拥有一个本地域名服务器,它有时也称为默认域名服务器。本地域名服务器离用户较近,一般不超过几个路由器的距离,也有可能就在同一个局域网中。本地域名服务器的IP地址需要直接配置在需要域名解析的主机中。

4.5 域名解析过程

计算机网络面试题 - 图32
计算机网络面试题 - 图33

  1. 在浏览器输入www.example.com,操作系统首先会查询4个缓存,分别是浏览器缓存、操作系统缓存(etc/hosts)、路由器缓存、ISP缓存(ISP 缓存就是你本地通信服务商的缓存,因为 ISP 维护着自己的 DNS 服务器,它缓存 DNS 记录的本质也是为了降低请求时间,达到快速响应的效果。)
  2. 如果缓存里查询不到,则会向本地域名服务器请求, 然后本地域名服务器将 www.example.com 的请求转发到 13台DNS 根名称服务器,根服务器返回「.com」顶级域名服务器地址
  3. 本地DNS服务器再次转发 www.example.com 的请求,这次转发到步骤2获取到的 .com 域的一个顶级域名服务器。顶级域名服务器返回[example.com]权威域名服务器的地址
  4. 本地DNS服务器再次转发 www.example.com 的请求,权限域名服务器查找 www.example.com 记录,获得相关值,例如,Web 服务器的 IP 地址 (192.0.2.44),并将 IP 地址返回。
  5. 本地DNS服务器最终获得用户需要的 IP 地址。解析程序将此值返回至 Web 浏览器。DNS 解析程序还会将 www.example.com 的 IP 地址缓存 (存储) 您指定的时长,以便它能够在下次有人浏览 www.example.com 时更快地作出响应。

从客户端到本地DNS服务器是属于递归查询,而DNS服务器之间就是的交互查询就是迭代查询。

5. HTTP协议

5.1 HTTP状态码

当浏览者访问一个网页时,浏览者的浏览器会向网页所在服务器发出请求。当浏览器接收并显示网页前,此网页所在的服务器会返回一个包含HTTP状态码的信息头(server header)用以响应浏览器的请求。


类别 原因短语 常用
1XX Informational(信息性状态码) 接收的请求正在处理
2XX Success(成功状态码) 请求正常处理完毕 200 OK 请求成功。一般用于GET与POST请求
201 Created 已创建。成功请求并创建了新的资源
202 Accepted 已接受。已经接受请求,但未处理完成
3XX Redirection(重定向状态码) 需要进行附加操作以完成请求
4XX Client Error(客户端错误状态码) 服务端无法处理请求 400 Bad Request 客户端请求的语法错误,服务器无法理解
401 Unauthorized 请求要求用户的身份认证
403 Forbidden 服务器理解请求客户端的请求,但是拒绝执行此请求
404 Not Found 服务器无法根据客户端的请求找到资源(网页)
405 Method Not Allowed 客户端请求中的方法被禁止
431 Request Header Fields Too Large 请求头字段太大
5XX Server Error(服务端错误状态码) 服务端处理请求出错 500 Internal Server Error 服务器内部错误,无法完成请求
502 Bad Gateway 作为网关或者代理工作的服务器尝试执行请求时,从远程服务器接收到了一个无效的响应
504 Gateway Time-out 充当网关或代理的服务器,未及时从远端服务器获取请求
505 HTTP Version not supported 服务器不支持请求的HTTP协议的版本,无法完成处理

5.2 各种协议与 HTTP 协议的关系

IP 协议、TCP 协议和 DNS 服务在使用 HTTP 协议的通信过程中各自发挥了哪些作用
计算机网络面试题 - 图34

5.3 HTTP长连接,短连接

在HTTP/1.0中默认使用短连接。也就是说,客户端和服务器每进行一次HTTP操作,就建立一次连接,任务结束就中断连接。当客户端浏览器访问的某个HTML或其他类型的Web页面中包含有其他的Web资源(如JavaScript文件、图像文件、CSS文件等),每遇到这样一个Web资源,浏览器就会重新建立一个HTTP会话。
而从HTTP/1.1起,默认使用长连接,用以保持连接特性。使用长连接的HTTP协议,会在响应头加入这行代码:

Connection:keep-alive

在使用长连接的情况下,当一个网页打开完成后,客户端和服务器之间用于传输HTTP数据的TCP连接不会关闭,客户端再次访问这个服务器时,会继续使用这一条已经建立的连接。Keep-Alive不会永久保持连接,它有一个保持时间,可以在不同的服务器软件(如Apache)中设定这个时间。实现长连接需要客户端和服务端都支持长连接。
HTTP协议的长连接和短连接,实质上是TCP协议的长连接和短连接。
—— 《HTTP长连接、短连接究竟是什么?》

5.4 HTTP是不保存状态的协议,如何保存用户状态?

HTTP 是一种不保存状态,即无状态(stateless)协议。也就是说 HTTP 协议自身不对请求和响应之间的通信状态进行保存。那么我们保存用户状态呢?Session 机制的存在就是为了解决这个问题,Session 的主要作用就是通过服务端记录用户的状态。典型的场景是购物车,当你要添加商品到购物车的时候,系统不知道是哪个用户操作的,因为 HTTP 协议是无状态的。服务端给特定的用户创建特定的 Session 之后就可以标识这个用户并且跟踪这个用户了(一般情况下,服务器会在一定时间内保存这个 Session,过了时间限制,就会销毁这个Session)。

在服务端保存 Session 的方法很多,最常用的就是内存和数据库(比如是使用内存数据库redis保存)。既然 Session 存放在服务器端,那么我们如何实现 Session 跟踪呢?大部分情况下,我们都是通过在 Cookie 中附加一个 Session ID 来方式来跟踪

Cookie 被禁用怎么办?
最常用的就是利用 URL 重写把 Session ID 直接附加在URL路径的后面
HTTP是无状态的.png

5.5 Cookie和Session有什么区别?Token?

【协议森林】彻底理解cookie、session、token
Cookie 和 Session都是用来跟踪浏览器用户身份的会话方式,但是两者的应用场景不太一样。
Cookie 一般用来保存用户信息 比如①我们在 Cookie 中保存已经登录过的用户信息,下次访问网站的时候页面可以自动帮你登录的一些基本信息给填了;②一般的网站都会有保持登录也就是说下次你再访问网站的时候就不需要重新登录了,这是因为用户登录的时候我们可以存放了一个 Token 在 Cookie 中,下次登录的时候只需要根据 Token 值来查找用户即可(为了安全考虑,重新登录一般要将 Token 重写);③登录一次网站后访问网站其他页面不需要重新登录。
Session 的主要作用就是通过服务端记录用户的状态。 典型的场景是购物车,当你要添加商品到购物车的时候,系统不知道是哪个用户操作的,因为 HTTP 协议是无状态的。服务端给特定的用户创建特定的 Session 之后就可以标识这个用户并且跟踪这个用户了。
Cookie 数据保存在客户端(浏览器端),Session 数据保存在服务器端。
Cookie 存储在客户端中,而Session存储在服务器上,相对来说 Session 安全性更高。如果要在 Cookie 中存储一些敏感信息,不要直接写入 Cookie 中,最好能将 Cookie 信息加密然后使用到的时候再去服务器端解密。

5.6 URI和URL的区别是什么?

  • URI(Uniform Resource Identifier) 是统一资源标志符,可以唯一标识一个资源。
  • URL(Uniform Resource Location) 是统一资源定位符,可以提供该资源的路径。它是一种具体的 URI,即 URL 可以用来标识一个资源,而且还指明了如何 locate 这个资源。

URI的作用像身份证号一样,URL的作用更像家庭住址一样。URL是一种具体的URI,它不仅唯一标识资源,而且还提供了定位该资源的信息。

5.7 GET和POST的区别是什么?

都9102年了,还问GET和POST的区别

分类 GET POST
后退按钮/刷新 无害 数据会被重新提交(浏览器应该告知用户数据会被重新提交)。
书签 可收藏为书签 不可收藏为书签
缓存 能被缓存 不能缓存
编码类型 application/x-www-form-urlencoded application/x-www-form-urlencoded 或 multipart/form-data。为二进制数据使用多重编码。
历史 参数保留在浏览器历史中。 参数不会保存在浏览器历史中。
对数据长度的限制 是的。当发送数据时,GET 方法向 URL 添加数据;URL 的长度是受限制的(URL 的最大长度是 2048 个字符)。 无限制。
对数据类型的限制 只允许 ASCII 字符。 没有限制。也允许二进制数据。
安全性 与 POST 相比,GET 的安全性较差,因为所发送的数据是 URL 的一部分。在发送密码或其他敏感信息时绝不要使用 GET ! POST 比 GET 更安全,因为参数不会被保存在浏览器历史或 web 服务器日志中。
可见性 数据在 URL 中对所有人都是可见的。 数据不会显示在 URL 中。

它们的本质都是 TCP 链接,并无区别。但是由于 HTTP 的规定以及浏览器/服务器的限制,导致它们在应用过程中可能会有所不同。
从标准上来看,GET 和 POST 的区别如下:

  • GET 用于获取信息,是无副作用的,是幂等的,且可缓存
  • POST 用于修改服务器上的数据,有副作用,非幂等,不可缓存

从报文来看,区别如下:

  • GET 请求行的方法是GET,如果有参数,参数应该放在 url 中
  • POST 请求行的方法是POST,如果有参数,参数应该放在 body中

5.8 HTTP和RPC的区别是什么?

image.png
image.png
rpc不仅仅可以用http协议实现。
http只是rpc的载体、传输协议。但是宽泛起来也可以说,是rpc的一种实现。
json(jsonrpc),xml(xmlrpc),protobuf,等都只是一种序列化方法(codec)。
http,tcp,mq等都是传输协议。
rpc中,jsonrpc和xmlrpc一般认为是使用json和xml作为序列化方法,使用http作为传输媒介的rpc协议。
grpc协议,序列化方法是protobuf,传输协议基于HTTP2。

rpc是远程过程调用,就是本地去调用一个远程的函数,而http是通过 url和符合restful风格的数据包去发送和获取数据。 rpc的一般使用的编解码协议更加高效,比如grpc使用protobuf编解码。而http的一般使用json进行编解码,数据相比rpc更加直观,但是数据包也更大,效率低下。 rpc一般用在服务内部的相互调用,而http则用于和用户交互。 HTTP 是应用层,在TCPIP之上。rpc是socket长链接(基于TCPIP)。另外,rpc还有注册发现,负载均衡,熔断,重试,日志,实时监控和管理。dubbo在这方面有自己的实现。HTTP的话,根据部署的不同,有不同的方案。

5.9 HTTP各版本区别

1.0和1.1的主要区别是什么?

这部分回答引用这篇文章 https://mp.weixin.qq.com/s/GICbiyJpINrHZ41u_4zT-A? 的一些内容。

HTTP1.0最早在网页中使用是在1996年,那个时候只是使用一些较为简单的网页上和网络请求上,而HTTP1.1则在1999年才开始广泛应用于现在的各大浏览器网络请求中,同时HTTP1.1也是当前使用最为广泛的HTTP协议。 主要区别主要体现在:

  1. 长连接 : 在HTTP/1.0中,默认使用的是短连接,也就是说每次请求都要重新建立一次连接。HTTP 是基于TCP/IP协议的,每一次建立或者断开连接都需要三次握手四次挥手的开销,如果每次请求都要这样的话,开销会比较大。因此最好能维持一个长连接,可以用个长连接来发多个请求。HTTP 1.1起,默认使用长连接 ,默认开启Connection: keep-alive。 HTTP/1.1的持续连接有非流水线方式和流水线方式 。流水线方式是客户在收到HTTP的响应报文之前就能接着发送新的请求报文。与之相对应的非流水线方式是客户在收到前一个响应后才能发送下一个请求。
  2. 错误状态响应码 :在HTTP1.1中新增了24个错误状态响应码,如409(Conflict)表示请求的资源与资源的当前状态发生冲突;410(Gone)表示服务器上的某个资源被永久性的删除。
  3. 缓存处理 :在HTTP1.0中主要使用header里的If-Modified-Since,Expires来做为缓存判断的标准,HTTP1.1则引入了更多的缓存控制策略例如Entity tag,If-Unmodified-Since, If-Match, If-None-Match等更多可供选择的缓存头来控制缓存策略。
  4. 带宽优化及网络连接的使用 :HTTP1.0中,存在一些浪费带宽的现象,例如客户端只是需要某个对象的一部分,而服务器却将整个对象送过来了,并且不支持断点续传功能,HTTP1.1则在请求头引入了range头域,它允许只请求资源的某个部分,即返回码是206(Partial Content),这样就方便了开发者自由的选择以便于充分利用带宽和连接。

1.1和2.0的主要区别是什么?

  1. HTTP2.0使用了多路复用的技术,做到同一个连接并发处理多个请求(Stream),而且并发请求的数量比HTTP1.1大了好几个数量级。HTTP1.1也可以多建立几个TCP连接,来支持处理更多并发的请求,但是创建TCP连接本身也是有开销的。
  2. 在HTTP1.1中,HTTP请求和响应都是由状态行、请求/响应头部、消息主体三部分组成。一般而言,消息主体都会经过gzip压缩,或者本身传输的就是压缩过后的二进制文件,但状态行和头部却没有经过任何压缩,直接以纯文本传输。随着Web功能越来越复杂,每个页面产生的请求数也越来越多,导致消耗在头部的流量越来越多,尤其是每次都要传输UserAgent、Cookie这类不会频繁变动的内容,完全是一种浪费。 HTTP1.1不支持header数据的压缩,HTTP2.0使用HPACK算法对header的数据进行压缩,这样数据体积小了,在网络上传输就会更快。
  3. 服务端推送是一种在客户端请求之前发送数据的机制。网页使用了许多资源:HTML、样式表、脚本、图片等等。在HTTP1.1中这些资源每一个都必须明确地请求。这是一个很慢的过程。浏览器从获取HTML开始,然后在它解析和评估页面的时候,增量地获取更多的资源。因为服务器必须等待浏览器做每一个请求,网络经常是空闲的和未充分使用的。为了改善延迟,HTTP2.0引入了server push,它允许服务端推送资源给浏览器,在浏览器明确地请求之前,免得客户端再次创建连接发送请求到服务器端获取。这样客户端可以直接从本地加载这些资源,不用再通过网络。

2.0和3.0的主要区别是什么?

HTTP2.0和HTTP3.0的区别在于前者使用tcp协议而后者使用udp协议。

5.10 HTTP 和 HTTPS 的区别?

  1. 端口 :HTTP的URL由“http://”起始且默认使用端口80,而HTTPS的URL由“https://”起始且默认使用端口443。
  2. 安全性和资源消耗:
    HTTP协议运行在TCP之上,所有传输的内容都是明文,客户端和服务器端都无法验证对方的身份。HTTPS是运行在SSL/TLS之上的HTTP协议,SSL/TLS 运行在TCP之上。所有传输的内容都经过加密,加密采用对称加密,但对称加密的密钥用服务器方的证书进行了非对称加密。所以说,HTTP 安全性没有 HTTPS高,但是 HTTPS 比HTTP耗费更多服务器资源。
    • 对称加密:密钥只有一个,加密解密为同一个密码,且加解密速度快,典型的对称加密算法有DES、AES等;
    • 非对称加密:密钥成对出现(且根据公钥无法推知私钥,根据私钥也无法推知公钥),加密解密使用不同密钥(公钥加密需要私钥解密,私钥加密需要公钥解密),相对对称加密速度较慢,典型的非对称加密算法有RSA、DSA等。

6. 报文、报文段、分组、包、数据报、帧、数据流的概念区别

  1. 报文(message)
    我们将位于应用层的信息分组称为报文。报文是网络中交换与传输的数据单元,也是网络传输的单元。报文包含了将要发送的完整的数据信息,其长短不需一致。报文在传输过程中会不断地封装成分组、包、帧来传输,封装的方式就是添加一些控制信息组成的首部,那些就是报文头。
  2. 报文段(segment)
    通常是指起始点和目的地都是传输层的信息单元。
  3. 分组/包(packet)
    分组是在网络中传输的二进制格式的单元,为了提供通信性能和可靠性,每个用户发送的数据会被分成多个更小的部分。在每个部分的前面加上一些必要的控制信息组成的首部,有时也会加上尾部,就构成了一个分组。它的起始和目的地是网络层
  4. 数据报(datagram)
    面向无连接的数据传输,其工作过程类似于报文交换。采用数据报方式传输时,被传输的分组称为数据报。通常是指起始点和目的地都使用无连接网络服务的的网络层的信息单元。
  5. 帧(frame)
    帧是数据链路层的传输单元。它将上层传入的数据添加一个头部和尾部,组成了帧。它的起始点和目的点都是数据链路层。
  6. 数据单元(data unit)
    指许多信息单元。常用的数据单元有服务数据单元(SDU)、协议数据单元(PDU)。
    SDU是在同一机器上的两层之间传送信息。PDU是发送机器上每层的信息发送到接收机器上的相应层(同等层间交流用的)。