网络协议与编程IO相关面试问题整理

文档大纲

1.TCP三次握手过程?第三条丢了会怎样?有什么现象?(高频考点)

背景知识回顾

传输控制协议TCP特点

TCP作为一种在网络通信中占据关键地位的传输层协议,具有独特的特性。它是面向连接(也可称作连接导向)的,并且具备高度可靠性,基于字节流进行数据传输。

在数据传输过程中,TCP会将用户数据精心打包成一个个报文段。发送报文段后,会立即启动一个定时器,用于监控数据的传输情况。当数据到达另一端时,接收方会对数据进行确认操作,同时,对于接收到的失序数据会重新进行排序,以恢复数据原本的顺序,对于重复的数据则直接丢弃。

TCP将连接视为最基础的操作对象,每一条TCP连接都包含两个端点,我们把这种端点称作套接字(socket)。套接字由端口号与IP地址拼接而成,比如192.1.1.6:50030,其中192.1.1.6是IP地址,50030是端口号。

TCP的基本特点如下:

  1. 面向连接且可靠:在数据传输前,会通过三次握手建立起可靠的连接,保障数据传输的稳定性和可靠性。它基于字节流进行数据传输,能确保数据的顺序性和完整性。
  2. 数据流分割与传输:会将应用层传来的数据流精准分割成一个个报文段,然后发送给目标节点的TCP层,实现数据的有序传输。
  3. 有序传输与重传机制:每个数据包都带有序号,接收方收到数据包后会发送ACK确认信息。若发送方在定时器规定时间内未收到ACK确认,就会重新传输该数据包,以此确保数据的准确送达。
  4. 校验和数据校验:运用校验和技术,对数据在传输过程中是否发生错误进行检验。一旦发现数据有误,便会采取相应措施进行纠正或重传,保证数据的正确性。

TCP报文头分析

  • 源端口(Source Port)/ 目的端口(Destination Port)

他们各占2个字节,标示该段报文来自哪里(源端口)以及要传给哪个上层协议或应用程序(目的端口)。

进行tcp通信时,一般client是通过系统自动选择的临时端口号,而服务器一般是使用知名服务端口号或者自己指定的端口号(比如DNS协议对应端口53,HTTP协议对应80)

  • 序号(Sequence Number)

占据四个字节,TCP是面向字节流的,TCP连接中传送的字节流中的每个字节都按顺序编号,例如如一段报文的序号字段值是107,而携带的数据共有100个字段,如果有下一个报文过来,那么序号就从207(100+107)开始,整个要传送的字节流的起始序号必须要在连接建立时设置。首部中的序号字段值指的是本报文段所发送的数据的第一个字节的序号

  • 确认序号(Acknowledgment Number)

4个字节,是期望收到对方下一个报文段的第一个数据字节的序号,若确认号=N,则表明:到序号N-1为止的所有数据都已正确收到,例如:B收到A发送过来的报文,其序列号字段是301,而数据长度是200字节,这表明了B正确的收到了A到序号500(301+200-1)为止的数据,因此B希望收到A的下一个数据序号是501,于是B在发送给A的确认报文段中,会把ACK确认号设置为501

  • 数据偏移(Offset)

4个字节,指出TCP报文段的数据起始处距离报文段的起始处有多远,这个字段实际上是指出TCP报文段的首部长度。由于首部中还有长度不确定的选项字段,因此数据偏移字段是必要的。单位是32位字,也就是4字节,4位二进制最大表示15,所以数据偏移也就是TCP首部最大60字节

  • 保留(Reserved)

6个字节,保留域

  • TCP Flags

控制位,由八个标志位组成,每个标志位表示控制的功能,我们主要来介绍TCP Flags中常用的六个:

URG(紧急指针标志):当URG=1时,表明紧急指针字段有效。它告诉系统此报文段中有紧急数据,应尽快传送(相当于高优先级的数据),而不要按原来的排队顺序来传送。例如,已经发送了很长的一个程序在主机上运行。但后来发现了一些问题,需要取消该程序的运行。因此用户从键盘发出中断命令。如果不使用紧急数据,那么这两个字符将存储在接收TCP的缓存末尾。只有在所有的数据被处理完毕后这两个字符才被交付接收方的应用进程。这样做就浪费了许多时间

ACK(确认序号标志):当ACK=1时确认号字段有效。当ACK=0时,确认号无效。TCP规定,在连接建立后所有的传送的报文段都必须把ACK置1

PSH(push标志):当两个应用进程进行交互式的通信时,有时在一端的应用进程希望在键入一个命令后立即就能收到对方的响应。在这种情况下,TCP就可以使用推送操作。这时,发送方TCP把PSH置1,并立即创建一个报文段发送出去。接收方TCP收到PSH=1的报文段,就尽快地交付接收应用进程,而不再等到整个缓存都填满了后向上交付

RST(重置连接标志):TCP连接中出现严重差错(如由于主机崩溃或其他原因),必须释放连接,然后再重新建立运输连接,可以用来拒绝一个非法的报文段或拒绝打开一个连接

SYN(同步序号,用于建立连接过程):在连接建立时用来同步序号。当SYN=1而ACK=0时,表明这是一个连接请求报文段。对方若同意建立连接,则应在相应的报文段中使用SYN=1和ACK=1。因此,SYN置为1就表示这是一个连接请求或连接接受保温。

FIN(finish标志,用于释放连接):当FIN=1时,表明此报文段的发送方的数据已发送完毕,并要求释放运输连接

  • 窗口(Window)

是TCP流量控制的一个手段。这里说的窗口,指的是接收通告窗口(Receiver Window,RWND)。它告诉对方本端的TCP接收缓冲区还能容纳多少字节的数据,这样就可以控制发送数据的速度。

  • 检验和(Checksum)

检验范围包括首部和数据两部分,由发送端填充,接收端对TCP报文段执行CRC算法以检验TCP报文段在传输过程中是否损坏。这也是TCP可靠传输的一个重要保障

  • 紧急指针(Urgent Pointer)

紧急指针仅在URG=1时才有意义,它指出本报文段中的紧急数据的字节数(紧急数据结束后就是普通数据)。因此,紧急指针指出了紧急数据的末尾在报文段中的位置。当所有紧急数据都处理完时,TCP就告诉应用程序恢复到正常操作。值得注意的是,即使窗口为零时也可发送紧急数据。

  • TCP可选项(TCP Options)

长度可变,最长可达40字节。当没有使用“选项”时,TCP的首部长度是20字节。

TCP的三次握手

所谓三次握手(Three-Way Handshake)即建立TCP连接,就是指建立一个TCP连接时,需要客户端和服务端总共发送3个包以确认连接的建立。在socket编程中,这一过程由客户端执行connect来触发,整个流程如下图所示:

在TCP/IP协议中,TCP协议提供可靠的连接服务,采用三次握手建立一个连接。

  • 第一次握手: 建立连接时,客户端发送SYN包(syn=j)到服务器,并进入SYN_SEND状态,等待服务器确认,SYN:同步序列编号(Synchronize Sequence Numbers)。
  • 第二次握手: 服务器收到 SYN 包,必须确认客户的 SYN(ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态;
  • 第三次握手: 客户端收到服务器的SYN + ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED(TCP连接成功)状态,完成三次握手。

为什么需要三次握手才能建立连接

为了初始化Sequence Number 的初始值,实现可靠数据传输, TCP 协议的通信双方, 都必须维护一个序列号, 以标识发送出去的数据包中, 哪些是已经被对方收到的。 三次握手的过程即是通信双方相互告知序列号起始值, 并确认对方已经收到了序列号起始值的必经步骤

如果只是两次握手, 至多只有连接发起方的起始序列号能被确认, 另一方选择的序列号则得不到确认

首次握手的隐患——SYN超时

问题起因分析:

  • 服务器收到客户端的SYN,回复SYN和ACK的时候未收到ACK确认
  • 服务器不断重试直至超时,Linux默认等待63秒才断开连接;(重复5次【不包括第一次】,从1秒开始,每次重试都翻倍:1+2+4+8+16+32=63秒)

针对SYN Flood的防护措施:

  • SYN队列满后,通过tcp_syncookies参数会发SYN cookie【源端口+目标端口+时间戳组成】
  • 若为正常连接则Client会回发SYN Cookie,直接建立连接;

保活机制:当我们建立连接后,Client出现故障怎么办?

  • 向对方发送保活探测报文,如果未收到相应则继续发送;
  • 尝试次数达到保活探测数仍未收到相应则中断连接;

2.TCP连接中的四次挥手?四次挥手的最后一个ack的作用是什么?为什么要time wait,为什么是2msl?(高频考点)

四次挥手

所谓四次挥手(Four-Way Wavehand)即终止TCP连接,就是指断开一个TCP连接时,需要客户端和服务端总共发送4个包以确认连接的断开。在socket编程中,这一过程由客户端或服务端任一方执行close来触发,整个流程如下图所示:

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

  • 第一次挥手: Client发送一个FIN,用来关闭Client到Server的数据传送,Client进入FIN_WAIT_1状态
  • 第二次挥手: Server收到FIN后,发送一个ACK给Client,确认序号为收到序号+1(与SYN相同,一个FIN占用一个序号),Server进入CLOSE_WAIT状态
  • 第三次挥手: Server发送一个FIN,用来关闭Server到Client的数据传送,Server进入LAST_ACK状态
  • 第四次挥手: Client收到FIN后,Client进入TIME_WAIT状态,接着发送一个ACK给Server,确认序号为收到序号+1,Server进入CLOSED状态,完成四次挥手

为什么会有TIME_WAIT状态

客户端连接在收到服务器的结束报文段之后,不会直接进入CLOSED状态,而是转移到TIME_WAIT状态。在这个状态,客户端连接要等待一段长为2MSL,即两倍的报文段最大生存时间,才能完全关闭,其原因主要有两点:

  • 确保有足够的时间放对方收到ACK包
  • 避免新旧连接混淆

为什么需要四次握手才能断开连接

因为TCP连接是全双工的网络协议,允许同时通信的双方同时进行数据的收发,同样也允许收发两个方向的连接被独立关闭,以避免client数据发送完毕,向server发送FIN关闭连接,而server还有发送到client的数据没有发送完毕的情况。所以关闭TCP连接需要进行四次握手,每次关闭一个方向上的连接需要FIN和ACK两次握手,发送发和接收方都需要FIN报文和ACK报文

服务器出现大量CLOSE_WAIT状态的原因

是由于对方关闭socket连接,我方忙于读或写,没有及时关闭连接

当客户端因为某种原因先于服务端发出了FIN信号,就会导致服务端被动关闭,若服务端不主动关闭socket发FIN给Client,此时服务端Socket会处于CLOSE_WAIT状态(而不是LAST_ACK状态)。通常来说,一个CLOSE_WAIT会维持至少2个小时的时间(系统默认超时时间的是7200秒,也就是2小时)。如果服务端程序因某个原因导致系统造成一堆CLOSE_WAIT消耗资源,那么通常是等不到释放那一刻,系统就已崩溃

解决方法:

  • 检查代码,特别是释放资源的代码
  • 查配置,特别是处理请求的线程配置

3.HTTP有哪些方法?返回状态码?

HTTP请求由三部分组成,分别是:请求行、消息报头、请求正文。

HTTP(超文本传输协议)是一个基于请求与响应模式的、无状态的、应用层的协议,常基于TCP的连接方式,HTTP1.1版本中给出一种持续连接的机制,绝大多数的Web开发,都是构建在HTTP协议之上的Web应用。 HTTP就是一个用文本格式描述报文头并用双换行分隔报文头和内容,在TCP基础上实现的请求-响应模式的双向通信协议。 以下是常见的HTTP方法和它们对应的返回状态码。

HTTP方法与描述:

方法 描述
GET 从服务器获取资源。
POST 向服务器提交数据,常用于提交表单数据或在服务器上创建新资源。
PUT 将数据发送到服务器以创建或更新资源。
DELETE 请求服务器删除指定的资源。
PATCH 部分更新资源,用于对资源的局部修改。
HEAD 类似于GET请求,但是只返回响应头部,不返回实体主体。
OPTIONS 获取目标URL所支持的通信选项,常用于CORS预检请求。
TRACE 用于追踪请求在经过的代理服务器上的传输路径。

HTTP状态码与描述:

状态码 描述
1xx 信息性状态码:请求已被接收,需要继续处理。
2xx 成功状态码:请求已成功被服务器接收、理解、并接受。
3xx 重定向状态码:需要进一步的操作以完成请求。
4xx 客户端错误状态码:服务器无法处理请求。
5xx 服务器错误状态码:服务器在处理请求的过程中发生了错误。

4. GET方法与POST方法的区别

特征 GET方法 POST方法
数据传输方式 数据通过URL的查询字符串传输 数据通过请求的主体传输
安全性 不适合传输敏感信息,数据在URL中可见 更适合传输敏感信息,数据不会在URL中可见
缓存 可被浏览器缓存 默认不可被浏览器缓存
幂等性 幂等的,多次请求结果相同 不幂等的,多次请求结果可能不同

5.HTTP报头格式是什么样的?实际中如何解析HTTP报头呢?

HTTP报头格式如下:

Header-Name: Header-Value

每个报头行由一个字段名和一个字段值组成,中间用冒号和空格分隔。报头行之间用换行符( \r\n)分隔。报头以一个空行结束,空行表示报头的结束,接下来是消息体(如果有)。

例如,以下是一个HTTP请求报头的示例:

GET /index.html HTTP/1.1
Host: www.example.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64)
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8

在这个示例中,每个报头行都由一个字段名和一个字段值组成,例如 Host: www.example.comUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64)

要解析HTTP报头,您可以使用以下步骤:

  1. 将HTTP报头按照换行符( \r\n)进行分割,得到各个报头行。
  2. 对每个报头行,使用冒号( :)进行分割,将字段名和字段值分离。
  3. 将字段名和字段值存储到一个数据结构中,例如字典或哈希表。

以下是一个简单的Python代码示例,演示如何解析HTTP报头:

def parse_http_header(header_string):
    headers = {}
    lines = header_string.split('\r\n')
    for line in lines:
        if ':' in line:
            header_name, header_value = line.split(':', 1)
            headers[header_name.strip()] = header_value.strip()
    return headers

# 示例HTTP报头
header_string = """GET /index.html HTTP/1.1
Host: www.example.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64)
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"""

# 解析HTTP报头
parsed_headers = parse_http_header(header_string)

# 打印解析后的HTTP报头
for name, value in parsed_headers.items():
    print(f'{name}: {value}')

6.URI和URL的区别

URI(Uniform Resource Identifier)和URL(Uniform Resource Locator)是用于标识互联网上资源的两个相关但不同的概念。

URI(统一资源标识符)

  • 定义:URI是一个用于标识某一资源的字符串的通用名称。它可以标识任何资源,不仅限于网络资源。
  • 组成:URI由两个主要部分组成,即URL和URN(统一资源名称)。URN是资源的名称,而URL则指定了资源的位置。
  • 示例mailto:[email protected]urn:isbn:0451450523

URL(统一资源定位符)

  • 定义:URL是URI的一种具体类型,用于指定资源的位置以及访问该资源的方式。

  • 组成:URL由以下部分组成:

    1. 协议(如HTTP、HTTPS、FTP等):指定访问资源所使用的协议。
    2. 主机名(如www.example.com):指定资源所在的主机。
    3. 路径(如/index.html):指定资源在主机上的位置。
    4. 可选部分:可能还包括端口号、查询参数和片段标识符等。
  • 示例http://www.example.com/index.htmlftp://ftp.example.com/files/document.pdf

区别:

  1. 范围:URI是一个通用的标识符,用于标识任何类型的资源,而URL是URI的一种具体类型,用于指定资源的位置和访问方式。
  2. 用途:URI用于唯一标识资源,而URL不仅唯一标识资源,还指定了如何访问该资源。
  3. 示例:URL是URI的一个子集,所以所有的URL都是URI,但并非所有的URI都是URL。URN也是URI的一种形式,但不是URL。

7.浏览器发生302跳转背后的逻辑?(高频考点)

当浏览器发生302跳转时,背后的逻辑大致如下:

  1. 发起原始请求:浏览器向服务器发送原始请求。

  2. 服务器响应302状态码:服务器接收到原始请求后,发现请求的资源已经被移到了另一个位置,于是返回一个带有302状态码的响应。

  3. 响应头中包含新的重定向地址:在响应中,服务器会包含一个 Location 头部字段,指示浏览器应该重定向到的新位置。这个字段的值就是新的资源位置的URL。

  4. 浏览器执行重定向:浏览器接收到包含302状态码的响应后,会根据响应中的 Location 字段的值,发起新的HTTP请求,访问该URL指示的资源。这个过程实际上是浏览器自动发起了第二个请求。

  5. 获取重定向后的资源:浏览器收到重定向后的响应后,会显示新的页面内容或执行其他操作,取决于重定向后的资源类型。

  6. 可能的循环重定向检测:浏览器在执行重定向时通常会检测是否存在循环重定向的情况,即多次重定向后又回到了原始请求的位置。如果检测到循环重定向,浏览器会中止重定向并显示相应的错误信息。

总的来说,302跳转背后的逻辑是浏览器接收到服务器的重定向指示后,自动发起新的请求,以访问新的资源位置。

8.简单说一下HTTP协议的交互流程?(高频考点)

HTTP协议的交互流程通常包括客户端向服务器发起请求,服务器接收请求并返回响应的过程。下面是HTTP协议的基本交互流程:

  1. 建立连接:客户端(例如Web浏览器)与服务器之间通过TCP/IP协议建立连接。HTTP协议运行在TCP/IP之上,因此在发送HTTP请求之前,需要建立TCP连接。
  2. 发送请求:客户端向服务器发送HTTP请求。请求由请求方法(例如GET、POST)、请求URL(指定要访问的资源)、请求头(包含请求的元数据信息)和请求体(可选,包含请求的数据)组成。
  3. 服务器处理请求:服务器接收到HTTP请求后,根据请求的内容和服务器端的配置,进行相应的处理。这可能包括验证用户身份、读取数据库、执行业务逻辑等操作。
  4. 发送响应:服务器根据请求的处理结果,生成HTTP响应,并将其发送回客户端。响应包括状态码(表示请求的处理结果)、响应头(包含响应的元数据信息)和响应体(包含响应的数据)。
  5. 接收响应:客户端接收到服务器发送的HTTP响应。客户端解析响应,并根据响应的内容采取相应的行动,例如显示网页内容、下载文件等。
  6. 关闭连接:通常情况下,一次HTTP请求-响应周期完成后,客户端和服务器之间的TCP连接会被关闭,释放资源。然而,HTTP/1.1中引入了持久连接(HTTP keep-alive),可以在一次连接中发送多个请求-响应对,提高性能。

这是HTTP协议的基本交互流程,通过这个流程,客户端和服务器之间可以进行有效的通信,实现数据的传输和资源的访问。

9.HTTP和HTTPS的差异?(高频考点)

HTTP(Hypertext Transfer Protocol)和HTTPS(Hypertext Transfer Protocol Secure)是用于在Web浏览器和Web服务器之间传输数据的两种协议。它们的主要区别在于安全性和数据传输方式:

特征 HTTP HTTPS
安全性 不安全,数据传输是明文的 安全,通过SSL/TLS对数据进行加密传输
数据传输方式 明文传输 加密传输
默认端口 80 443

10.SSL/TLS的交互流程?

SSL(Secure Sockets Layer)和TLS(Transport Layer Security)是用于在网络上安全传输数据的协议,TLS是SSL的继任者,也是现代加密通信的标准。SSL/TLS的交互流程大致如下:

握手阶段

  • 客户端向服务器发送一个握手请求,其中包含支持的SSL/TLS版本、加密算法、压缩算法等信息。
  • 服务器收到客户端的握手请求后,向客户端发送一个握手响应,其中包含服务器证书(公钥)、支持的SSL/TLS版本、加密算法等信息。
  • 客户端收到服务器的握手响应后,验证服务器的证书是否合法和可信,并生成一个会话密钥(Session Key)。
  • 客户端使用服务器的公钥加密会话密钥,并将其发送给服务器。
  • 服务器收到客户端发送的加密的会话密钥后,使用自己的私钥解密,并确认客户端和服务器都拥有了相同的会话密钥。

加密通信阶段:握手阶段完成后,客户端和服务器之间的通信会使用会话密钥进行加密和解密,保证了数据在传输过程中的安全性。

数据传输阶段:客户端和服务器之间进行数据传输,传输的数据会使用会话密钥进行加密,保护了数据的隐私性和完整性。

SSL/TLS的握手阶段确保了客户端和服务器之间的通信建立在安全的基础之上,保证了数据在传输过程中的安全性和完整性。

11.Rest和Http什么关系? 大家都说Rest很轻量,你对Rest风格如何理解?(高频考点)

当谈及REST和HTTP的关系时,可以将其比喻为建筑物和建筑材料的关系。

  • HTTP:就像是建筑材料,是一种用于在网络上传输数据的协议。HTTP定义了客户端和服务器之间如何传输数据的规则和约定,包括请求和响应的格式、通信的方法(GET、POST等)、状态码的含义等。HTTP是REST的基础,它提供了通信的基础设施,但本身并不关心如何组织和设计系统。

  • REST:就像是建筑物,是一种软件架构风格,用于设计分布式系统。REST强调资源的概念,将系统中的各种实体抽象为资源,并通过HTTP协议来操作这些资源。REST定义了一套设计原则和规范,包括资源的标识、统一的接口、无状态性、客户端-服务器架构等。REST利用HTTP的各种特性来实现系统的设计,使得系统更加简单、可靠和可扩展。

因此,HTTP是REST的基础,REST利用HTTP作为通信的基础设施来设计和实现分布式系统。就像建筑物需要建筑材料来构建一样,REST需要HTTP来实现分布式系统的设计。

当我们说REST很轻量时,可以这样理解:

  1. 简单的通信方式:REST使用HTTP作为通信协议,而HTTP是一种非常简单、通用的协议,它已经被广泛应用于互联网中,因此REST不需要额外的复杂通信协议。

  2. 无需繁琐的封装:相比于一些复杂的Web服务协议(如SOAP),REST不需要复杂的消息封装和解析过程。REST的数据通常以简单的JSON或XML格式传输,不需要额外的标记语言或协议。

  3. 灵活的接口设计:REST接口设计遵循简洁的原则,资源以URL形式暴露,使用标准的HTTP方法进行操作。这种设计使得REST接口更加直观、易于理解和使用,不需要额外的说明文档或培训。

  4. 适应性强:由于REST使用HTTP作为通信协议,并且采用了一些通用的设计原则,因此它适用于各种不同的场景和应用,包括Web应用、移动应用、物联网设备等。

  5. 性能优异:由于REST的通信开销小,数据量少,响应速度快,因此它在性能方面表现优异,适用于对性能有要求的场景。

REST之所以被称为轻量级,是因为它使用简单的通信方式、无需复杂的封装、接口设计灵活简洁、适应性强、性能优异等特点,使得它成为一种非常轻便、高效的分布式系统设计风格。

12.TCP的滑动窗口协议有什么用?讲讲原理。(高频考点)

TCP的滑动窗口协议主要用于两个方面:流量控制和可靠传输。

  1. 流量控制:滑动窗口协议允许发送方和接收方之间动态调整数据传输的速率,以适应网络条件和接收方的处理能力。发送方根据接收方的窗口大小调整发送数据的速率,避免发送过多的数据导致接收方缓冲区溢出。接收方通过调整窗口大小告知发送方自己的接收能力,从而实现了对数据流量的控制。

  2. 可靠传输:滑动窗口协议使得TCP能够在不可靠的网络环境下实现可靠的数据传输。发送方在发送数据后等待接收方的确认信息,确认信息包含了接收方已经成功接收的数据量和当前的接收窗口大小。如果发送方没有收到确认信息,或者接收方的窗口已满,发送方会停止发送数据,并进行相应的重传或等待操作,直到接收方重新开启窗口或确认信息到达。

通过滑动窗口协议,TCP能够实现流量控制和可靠传输的功能,保证了数据在传输过程中的有效性和完整性,同时也最大化了网络的利用率。以下是其主要原理:

发送窗口和接收窗口

  • 发送方维护一个发送窗口,它定义了发送方可以连续发送的数据量。
  • 接收方维护一个接收窗口,它定义了接收方当前能够接受的数据量。

滑动窗口

  • 发送窗口和接收窗口之间的差值称为滑动窗口。滑动窗口的大小随着数据的发送和接收而动态调整。
  • 发送方和接收方通过滑动窗口的大小来协调数据的传输速率,以适应网络的情况和接收方的处理能力。

流量控制

  • 发送方根据接收方的窗口大小调整发送数据的速率,避免发送过多的数据导致接收方缓冲区溢出。
  • 接收方通过调整窗口大小告知发送方自己的接收能力,从而控制发送方的数据流量。

可靠传输

  • 发送方发送数据后等待接收方的确认信息。
  • 接收方收到数据后发送确认信息,确认信息包含了接收方已经成功接收的数据量和当前的接收窗口大小。
  • 如果发送方没有收到确认信息,或者接收方的窗口已满,发送方会停止发送数据,并进行相应的重传或等待操作,直到接收方重新开启窗口或确认信息到达。

通过滑动窗口协议,TCP实现了对数据传输速率和流量的有效控制,同时也确保了数据的可靠传输。发送方和接收方之间的窗口大小动态调整,使得数据在传输过程中能够更加高效地进行交换。

13.说一下HTTP的断点续传?解决方法是?

HTTP的断点续传是指在文件下载过程中,如果下载中断或者用户手动暂停了下载,可以在之后恢复下载的功能。这样可以节省用户的时间和网络带宽,提高下载的效率。可以表达为如下:

  1. 下载中断:下载过程中,如果网络中断、服务器故障或用户手动中断了下载,会导致下载中断。

  2. 记录下载位置:在HTTP请求中,服务器可以通过 Range 头部字段告知客户端文件的下载范围。客户端可以利用这个信息记录已经下载的文件位置。

  3. 恢复下载:当用户重新发起下载请求时,客户端可以将记录的已下载位置发送给服务器,并通过 Range 头部字段请求未下载的文件片段,实现断点续传。

解决方法:

  1. 服务器支持范围请求:服务器需要支持HTTP协议的范围请求(Range Requests),能够根据客户端请求的范围返回对应的文件片段。

  2. 客户端记录已下载位置:客户端需要记录已经下载的文件位置,通常通过保存已下载的字节数或者文件片段的起始位置来实现。

  3. 发送范围请求:当用户重新发起下载请求时,客户端将记录的已下载位置通过 Range 头部字段发送给服务器,并请求未下载的文件片段。

  4. 服务器返回文件片段:服务器接收到范围请求后,根据客户端请求的范围返回对应的文件片段,并附带 206 Partial Content 状态码。

  5. 合并文件片段:客户端接收到文件片段后,将其与已经下载的文件片段合并,最终完成文件的下载。

通过这种方式,HTTP的断点续传功能可以使用户在下载过程中更加灵活,避免因下载中断而导致的重新下载或者文件损坏的问题,提高了下载的效率和用户体验。

14.说说http协议的多线程下载原理以及实现步骤?有啥优势?

HTTP协议的多线程下载是一种利用多线程技术加速文件下载的方法。它通过同时使用多个线程分别从服务器下载文件的不同部分,并将这些部分合并成完整的文件,以提高下载速度和效率。

工作原理:

  1. 文件分割:客户端将要下载的文件分割成多个部分,每个部分大小相等或者根据网络情况动态调整。

  2. 多线程下载:客户端启动多个线程,每个线程负责下载文件的一个部分。每个线程使用单独的HTTP请求从服务器下载文件的指定部分。

  3. 并发下载:多个线程同时运行,可以并发地从服务器下载文件的不同部分。这样可以充分利用带宽和网络资源,提高下载速度。

  4. 文件合并:当所有部分的文件下载完成后,客户端将这些部分合并成完整的文件。合并可以在内存中进行,也可以将部分文件保存到磁盘上再进行合并。

实现步骤:

  1. 确定文件大小:客户端发送HEAD请求获取要下载文件的大小,以便确定文件的分割和下载范围。

  2. 分割文件:根据文件大小和线程数,确定每个线程需要下载的文件范围。

  3. 创建线程:根据分割后的文件范围,创建相应数量的线程,并分配给它们各自的下载任务。

  4. 下载文件:每个线程使用HTTP请求下载指定范围的文件部分,并保存到本地。

  5. 合并文件:当所有线程完成下载后,将各个部分的文件合并成完整的文件。

优点:

  1. 提高下载速度:多线程下载充分利用了网络带宽和服务器资源,可以显著提高文件下载速度。

  2. 减少下载时间:通过并发下载,可以减少整个下载过程的时间,提高了下载效率。

  3. 提高下载稳定性:多线程下载可以分散网络波动和服务器压力,提高了下载的稳定性和成功率。

注意事项:

  1. 服务器支持:服务器需要支持同时处理多个下载请求,并且支持多线程下载的文件断点续传。

  2. 资源竞争:需要注意线程间的资源竞争问题,如文件写入、线程同步等。

  3. 线程数选择:线程数过多可能会导致服务器压力增加,线程数过少可能无法充分利用带宽。需要根据实际情况进行合理调整。

15.什么是长连接和短链接?举例说明(高频考点)

长连接(Keep-Alive)和短连接是指在HTTP协议中控制连接状态的两种机制。

长连接(Keep-Alive)

  • 定义:长连接是指客户端与服务器之间建立的TCP连接在一次请求-响应完成后保持打开状态,可以被多次复用来发送多个HTTP请求和接收多个HTTP响应。

  • 优点

    1. 减少了连接的建立和关闭开销,节省了网络资源。
    2. 可以减少延迟,提高了性能。
    3. 对于具有频繁交互的Web应用,长连接可以减少服务器的负载。
  • 举例:一个客户端需要从服务器下载多个静态资源(例如图片、样式表、脚本等),使用长连接可以在建立一次TCP连接后,通过该连接发送多个HTTP请求,从而减少了建立和关闭连接的开销。

短连接

  • 定义:短连接是指客户端与服务器之间建立的TCP连接在一次请求-响应完成后立即关闭,不保持连接状态,下次请求需要重新建立连接。

  • 优点

    1. 对服务器的负载更为轻量,因为连接较短,不会占用过多的资源。
    2. 对于一些临时性的请求,如获取动态页面、少量静态资源等,短连接可以更好地适应。
  • 举例:当用户通过浏览器访问某个网站时,浏览器发送HTTP请求获取网页内容,请求完成后即关闭连接,这就是一种典型的短连接的例子。

总的来说,长连接适用于需要频繁交互的场景,能够提高性能和降低延迟;而短连接适用于一次性的请求,能够减轻服务器负载和资源消耗。具体选择长连接还是短连接,需要根据实际的应用场景和性能需求来确定。

16.一个典型的客户端集群->LB->服务端集群这样的结构中,如客户端采用连接池,长连接的方式,这种设计你觉得可能会出现什么问题?

16.cookie和session解决什么问题,相同点和不同点?(高频考点)

Cookie和Session都是用于在Web应用中跟踪用户状态和身份的机制,但它们解决的问题以及其相同点和不同点如下:

解决的问题:

  • 身份认证:Cookie和Session都可以用于用户身份认证,确保用户的安全访问。

  • 状态跟踪:Cookie和Session都可以用于跟踪用户的状态,如登录状态、购物车内容等。

相同点:

  • 存储信息:无论是Cookie还是Session,都可以在客户端和服务器端之间存储信息,用于跟踪用户状态和身份。

  • 实现用户认证:Cookie和Session都可以用于实现用户的身份认证,以确保安全访问。

  • 跟踪用户状态:无论是Cookie还是Session,都可以用于跟踪用户的状态,例如登录状态、购物车内容等。

不同点:

特点 Cookie Session
存储位置 存储在客户端(浏览器)中 存储在服务器端
安全性 相对较低,容易被篡改和窃取 相对较高,存储在服务器端
生命周期 可以设置过期时间,持久性可控 通常随着浏览器关闭或超时而清除,服务器控制
传输方式 随着HTTP请求头发送到服务器 通过Cookie携带Session ID,实际数据存储在服务器端

总的来说,Cookie和Session都用于解决Web应用中的用户身份认证和状态跟踪问题,但它们的存储位置、安全性、生命周期和传输方式有所不同,适用于不同的场景和需求。

17.了解session集群解决方案,通用解决方案?(高频考点)

Session集群解决方案是指在分布式环境下,通过某种机制确保Session数据能够在多个服务器之间共享和同步,从而实现用户跨服务器的状态保持和访问一致性。这对于需要在多个服务器上部署Web应用,并保持用户会话状态的应用场景非常重要。

Session粘滞(Sticky Session)

  • 在负载均衡器(如Nginx、HAProxy等)前,通过某种算法(如轮询、IP哈希等)将同一个用户的请求定向到同一个服务器上,使得同一个用户的Session始终在同一个服务器上处理。
  • 优点:简单易实现,无需修改应用代码。
  • 缺点:可能导致服务器负载不均衡,容易成为性能瓶颈。

Session复制(Session Replication)

  • 将Session数据复制到所有服务器节点,保持数据同步。
  • 优点:保证了Session数据的一致性,适用于小规模集群。
  • 缺点:会增加网络负载和内存占用,不适用于大规模集群。

集中式Session存储

  • 将Session数据存储在共享的外部存储(如数据库、缓存服务器等),所有服务器节点共享同一份Session数据。
  • 优点:减少了数据冗余和复制,适用于大规模集群。
  • 缺点:可能成为性能瓶颈,对外部存储的性能和可靠性有一定要求。

分布式缓存方案

  • 使用分布式缓存(如Redis、Memcached等)存储Session数据,所有服务器节点通过缓存服务共享Session数据。
  • 优点:性能较高,可靠性较好,适用于大规模集群。
  • 缺点:部署和维护成本较高,需要额外的缓存服务器。

数据库存储方案

  • 将Session数据存储在数据库中,所有服务器节点通过数据库共享Session数据。
  • 优点:数据持久化,适用于需要数据安全性和一致性的应用。
  • 缺点:性能相对较低,对数据库的压力较大。

不同的解决方案适用于不同的应用场景和需求,选择合适的Session集群解决方案需要考虑到应用的规模、性能要求、可靠性要求以及成本等因素。

18.HTTP的安全校验主要有几种?可以说说?(高频考点)

  1. SSL/TLS加密:使用SSL(安全套接层)或TLS(传输层安全)协议对HTTP通信进行加密,保护数据在传输过程中的安全性。通过在客户端和服务器之间建立安全的加密通道,防止数据被窃取或篡改。常见的实现方式包括HTTPS协议。

  2. 数字证书:使用数字证书验证服务器的身份,确保通信双方的真实性和完整性。服务器需要使用数字证书来证明自己的身份,并且客户端可以通过验证数字证书的合法性来确认服务器的身份。

  3. 身份认证:对客户端和服务器进行身份认证,确保通信双方的身份合法。常见的身份认证方式包括基本身份认证(使用用户名和密码)、摘要身份认证(使用摘要算法)、客户端证书认证等。

  4. 访问控制:对HTTP请求进行访问控制,限制特定用户或者特定权限的访问。可以通过访问控制列表(ACL)、角色-based访问控制(RBAC)等方式来实现。

  5. 防止重放攻击:使用随机数、时间戳等机制防止重放攻击,确保每个请求都是唯一的。可以使用一次性令牌(One-Time Token)或者防重放令牌(Anti-Replay Token)来实现。

  6. 数据完整性校验:对HTTP数据进行完整性校验,确保数据在传输过程中没有被篡改。常见的实现方式包括消息摘要(Message Digest)和数字签名(Digital Signature)等。

19.epoll、select、poll原理

epoll、select和poll是常用的I/O多路复用机制,用于处理并发的I/O操作。 它们在不同的操作系统上实现了类似的功能,允许程序同时监视多个文件描述符(sockets、文件等),并在其中任意一个文件描述符就绪时进行相应的操作。

select

select是最早出现的I/O多路复用函数之一。它通过将待监视的文件描述符按位图方式传递给select函数,然后select函数会阻塞并等待任意一个文件描述符就绪。 它适用于较小的并发连接数场景,因为它有文件描述符数量限制

poll

poll是select的改进版本, 解决了select的文件描述符数量限制问题。与select不同,poll使用一个pollfd结构数组来传递待监视的文件描述符,每个结构体中保存了要监视的文件描述符及其关注的事件。poll函数会阻塞并等待任意一个文件描述符就绪。

epoll

epoll是Linux特有的I/O多路复用机制。它 通过epoll_create函数创建一个epoll实例,并使用epoll_ctl函数向其中添加或修改要监视的文件描述符和关注的事件。与select和poll不同,epoll将就绪的文件描述符放入一个就绪列表中,而不是阻塞等待,然后程序可以通过epoll_wait函数从就绪列表中获取就绪的文件描述符进行处理。

epoll相对于select和poll的优势在于:

  • 没有文件描述符数量限制,支持大规模并发连接。
  • 使用回调机制,只返回就绪的文件描述符,避免遍历整个文件描述符集合。
  • 支持边缘触发模式,即只在状态发生变化时通知,提高效率。

总而言之,epoll、select和poll都是用于实现I/O多路复用的机制,选择使用哪种机制取决于具体的应用场景和操作系统支持。在Linux系统上,epoll通常是最佳选择,尤其对于大规模并发的网络应用。

20.基于BIO实现的Server端,当建立了100个连接时,会有多少个线程?如果基于NIO,又会是多少个线程? 为什么?

基于BIO(阻塞式IO)实现的服务器端,在每个客户端连接时都会创建一个新的线程来处理该连接,因此当建立了100个连接时,会有100个线程。

而基于NIO(非阻塞IO)实现的服务器端,使用一个线程来管理多个连接,因此不会为每个连接创建一个新的线程。在NIO模型中,一个线程可以同时管理多个连接,通过使用选择器(Selector)来实现多路复用,当有IO事件发生时,可以通过单个线程来处理多个连接的IO操作。因此,即使有100个连接,基于NIO的服务器端也只需要一个线程来管理这些连接,不会创建额外的线程。

这种差异的原因在于BIO模型中,每个连接都需要独立的线程来处理IO操作,因此随着连接数量的增加,线程数量也会线性增加;而NIO模型中,通过事件驱动的方式实现了多路复用,使得单个线程可以有效地管理多个连接,从而避免了线程数量随连接数量增加而线性增加的问题。

21.通常来说基于NIO实现的Server端,会用多少个线程去处理IO事件,为什么?

通常来说,基于NIO实现的服务器端只需要使用一个线程去处理IO事件。这个单独的线程通过选择器(Selector)实现多路复用,可以同时管理多个连接的IO操作。

使用单个线程处理多个连接的IO事件的好处已经在之前的回答中提到了。单线程模型消耗的资源更少,避免了线程安全问题和竞态条件,简化了编程模型,并且具有更好的可伸缩性。因此,在大多数情况下,基于NIO实现的服务器端只需要一个线程来处理IO事件。

这是因为基于NIO的服务器端利用了操作系统提供的多路复用机制,主要是通过选择器(Selector)实现的。选择器可以监视多个通道的IO事件,例如读、写、连接等,一旦某个通道有IO事件发生,选择器就会将该事件通知给单独的IO线程进行处理。

使用单个线程处理多个连接的IO事件,有以下几个原因:

  1. 资源效率高: 单线程模型消耗的资源更少。与为每个连接创建一个新线程相比,单个线程管理多个连接减少了线程的创建和上下文切换的开销,节约了系统资源。

  2. 简化编程模型: 单线程模型相对于多线程模型更简单,编程难度更低,代码更易于理解和维护。

  3. 避免了竞态条件和线程安全问题: 在单线程模型中,不需要考虑多线程并发访问共享资源的问题,避免了线程安全的麻烦。

  4. 更好的可伸缩性: 单线程模型可以更容易地实现负载均衡,通过水平扩展多个服务器实例来处理更多的连接。

通过单个线程管理多个连接的IO事件,基于NIO的服务器端可以实现更高效、更稳定和更可伸缩的IO处理。

参考书籍、文献和资料

  1. 说说TCP的三次握手和四次挥手

  2. HTTP常见的请求方法和状态码

  3. Web开发HTTP协议知识_常用http方法、http状态码等(前端开发和面试必备))

原文阅读