计算机网络八股

本篇以Q&A的形式给出

HTTP

能否详细解释「超文本传输协议」?

超文本:不止可以传输字符,还可以传输图片、音频等。传输:双向收发、可以有中间代理。

HTTP 常见的状态码有哪些?

2成功  3重定向  4客户端错误  5服务器错误

HTTP 常见字段有哪些?

host:主机      content-type:内容编码格式     content-length:内容长度 

content-encoding:压缩方式

GET 和 POST 有什么区别?

get是获取,post是提交。get不需要消息体(没规定一定不能带,所以理论上真带也行),post需要。get幂等,post不幂等。get安全,post不安全(安全指的是是否会改变服务器上的数据内容)

HTTP 缓存有哪些实现方式?

强制缓存和协商缓存。强制缓存指的是对缓存资源设置一个过期时间(相对时间cache control或绝对时间expires,优先使用相对时间),在这个时间内就使用缓存,超过这个时间就重新向服务器请求。协商缓存指的是每次使用的时候都向服务器发起一个请求,看根据请求结果判断是否使用缓存。请求有两种:If-none-match和Etag、Last-modified和If-modified-since。前一个是比较缓存内容和服务器内容是否相同,后一个是看在缓存之后服务器的数据是否发生更改。Last-modified有几个问题:可能数据没更改但最后修改时间发生变化、这个参数是秒级的,不适合频繁修改的内容。一般会强制缓存和协商缓存联合使用,即强制缓存过期后使用协商缓存

HTTP/1.1 的优点有哪些?

长连接。简单,易于扩展,跨平台。(1的数据就已经可以被压缩了,选择对应的压缩算法就行,Hpack压缩的是头部信息)

HTTP/1.1 的缺点有哪些?

无状态,明文传输,队头阻塞(服务器端的,需要顺序处理)

HTTP 与 HTTPS 有哪些区别?

在HTTP的基础上实现了SSL/TSL协议,实现了加密传输。HTTP需要TCP的三次握手建立链接,HTTPs需要TCP的三次加TSL的几次(版本不一样的TSL握手次数也不一样)。

HTTPS 解决了 HTTP 的哪些问题?

窃听(通过加密实现),篡改(通过指纹(摘要算法)实现),冒充(通过CA证书实现)

加密:混合加密。在链接的时候使用非对称加密,传输的时候使用对称加密。

指纹:对内容和数字签名生成一个哈希值。(当然这个哈希值也需要加密)

CA证书:服务器把自己的公钥注册到CA机构,CA机构用自己私钥给服务器的公钥加密并颁发一个数字证书给服务器。服务器在和客户端链接的时候会把这个数字证书发给客户端,客户端用CA的公钥把这个证书解密并查询是否过期,是否真实,如果没问题的话就用服务器发来的这个公钥对内容进行加密并发回给服务器。

HTTPS 是如何建立连接的?其间交互了什么?

首先进行TCP的三次握手,然后TSL的握手。版本不一样的TSL握手流程不一样。这里说RSA的四次和1.3的两次。

RSA的四次:客户端向服务器发送一个随机数a,压缩格式和可选的TSL版本;服务器向客户端发送一个随机数b,服务器的CA证书和选择的TSL版本;客户端验证CA证书是否正常,正常的话从证书中取出服务器的公钥,再生成一个预主密钥并发送给服务器。这是服务器和客户端都有了两个随机数加一个预主密钥,用这些共同生成一个秘钥作为接下来通话的秘钥。RSA主要的作用就是生成了预主密钥

TLS1.3:不再用RSA的加密方法,而是选择ECDHE。换了一种新的加密算法,这时服务器和客户端两方都只需要发送一次数据就可以了。所以可以实现在一个RTT内完成握手。下次再使用的话,如果可以复用上次的秘钥,那么直接用,就不需要握手了,也就是所谓的0-RTT。

ECDHE算法:(Elliptic Curve Diffie-Hellman Ephemeral,椭圆曲线、DH、暂时)这个算法主要基于DH算法。DH算法的思路是指定一个离散对数的计算方法,即指定对数的底数和后面要计算的模数。客户端生成一个数a,计算a的离散对数A,服务器生成一个数b,计算b的离散对数B。那么对于客户端和服务器,就有B^a=A^b=K,这个K只有服务器和客户端能计算出来,这个就是交流要用的秘钥。剩下的EC和E都是对算法的改进,E指的是每次通信都随机生成一个秘钥,EC指的是椭圆曲线,这是为了减少计算量用的(取模计算太慢了)。

客户端校验数字证书的流程是怎样的?

不考虑信任链的话,客户端用自己储存的CA公钥对证书解密,并通过哈希值检验内容是否被更改。如果没问题的话就看颁发这个证书的机构是否被信任,正数是否过期。如果都没问题就用。

考虑信任链的话,服务器会发送多个证书,包含服务器证书和中间机构的证书。客户端先验证中间机构的证书,合格的话再验证服务器的证书。验证方法和不考虑信任链是一样的

为什么抓包工具能截取 HTTPS 数据?

其实就是抓包工具自己签发了一个被浏览器信任的证书,作为一个类似于中继服务器的存在。

HTTP/1.1 相比 HTTP/1.0 提高了什么性能?

实现了长连接和管道传输(一个请求发送完,不需要等到返回回来就可以发送下一个),但很多浏览器其实不支持管道传输

HTTP/2 做了什么优化?
  • 集成了HTTPS(TSL),实现了安全传输。
  • 集成了Hpack,实现了头部信息压缩传输。
  • 实现了流传输:可以同时发送多个请求,而不需要新开管道,服务器可以主动推送资源。
  • 实现了二进制格式(和HTTP1相比少了一步把报文转化为文字的内容)
HTTP/3 做了哪些优化?

集成了QUIC:实现了UDP可靠传输的应用层实现,避免了服务器端的对头阻塞,方便了连接迁移和建立链接。注意,QUIC并不只是实现了UDP可靠传输,他同时还集成了TLS和QPack等内容

也就是说这个关于HTTP3的解释并不准确,HTTP3应该是HTTP+QPack+QUIC+UDP,TLS被集成到了QUIC中

HTTPS 如何优化?

这个主要优化点在协议、会话和证书上。

协议就是使用更方便的TLS1.3,在第一次连接时就可以1-RTT实现,后续更是可以根据缓存的秘钥实现0-RTT(只不过此时需要避免重放攻击,只能用于get方法等)。使用ECDHE算法,更快更安全。

会话就是服务端储存sessionID,再链接的时候带上sessionID就可以跳过握手过程。或者客户端储存session-Ticket,这个ticket不是一个简单的id,而是服务器发给客户端的加密后的数据(用服务器端的秘钥加密),这个数据在TCP握手的时候发给服务器,如果服务器对这个数据解析后认为这个是有效的,就告诉客户端可以用这个ticket,客户端就用这个ticket中的内容回复出秘钥进行使用

证书的优化主要在证书有效性的查询上,把证书是否有效和证书一块给客户端发过去

RPC

RPC 远程控制调用。说白了其实就是一个企业自己实现的HTTP协议。由于不需要考虑过多的兼容,所以可以自己简化一些内容,是的传输更快更方便

webSocket和HTTP

websocket和socket完全不一样。他是一个全双工的的应用层通信协议,目的是为了使服务端可以向客户端主动发消息。HTTP服务端只能在收到客户端请求后才能发送信息,但websocket中服务端可以向客户端主动推送消息。在一般的应用中,会先建立HTTP的长连接,然后将协议转为websocket

TCP

TCP 头格式有哪些?

源端口,目的端口。序列号,确认号。标志位,窗口大小,校检和,紧急指针,选项。(没有包长度)

为什么需要 TCP 协议? TCP 工作在哪一层?

实现面向连接的可靠传输 工作在传输层

什么是 TCP ?

面相连接的可靠字节流传输。面相连接:通过一组四元数(因为协议已经相同了)标志,一对端口只能建立一个一次连接。可靠:通过重传机制保证数据按顺序,无损的到达上层。字节流:都是二进制传输的,不保留消息边界

什么是 TCP 连接?

保证可靠传输和流量控制的一系列状态信息。比如源目的端口,窗口大小,socket,序列号

如何唯一确定一个 TCP 连接呢?

确定一个链接需要源、目的的端口和ip加上协议的五元数,这里协议已经确定,所以只需要前面说的四元数

有一个 IP 的服务端监听了一个端口,它的 TCP 的最大连接数是多少?

理论来说是客户端ip个数乘端口数

UDP 和 TCP 有什么区别呢?分别的应用场景是?

TCP面向连接,可靠传输。UDP无连接(UDP头部:源端口目的端口,包长度,校检和)。TCP有流量控制,UDP没有。TCP主动分片,UCP不会。

TCP:FTP。Http等。UDP:允许出错,更注重效率的场景,比如语音通话等

为什么 UDP 头部没有「首部长度」字段,而 TCP 头部有「首部长度」字段呢?

TCP包长可变,UDP包长不可变

为什么 UDP 头部有「包长度」字段,而 TCP 头部则没有「包长度」字段呢?

历史原因

TCP 和 UDP 可以使用同一个端口吗?

可以

多个 TCP 服务进程可以同时绑定同一个端口吗?

不开reuseport参数的话不能主动bind

重启 TCP 服务进程时,为什么会出现“Address in use”的报错信息?又该怎么避免?

源端口依然处于time_wait状态,没有完全关闭。执行bind函数的时候就会返回错误

开so_reuseAddress参数,使得socket可以bind处于time_wait状态的端口

多个 TCP 服务进程可以绑定同一个端口吗?

随机分配的话都没问题,主动bind的话需要开reuseport参数

客户端的端口可以重复使用吗?

可以连多个不同的服务端端口,可以和不同的协议共用。

客户端 TCP 连接 TIME_WAIT 状态过多,会导致端口资源耗尽而无法建立新的连接吗?

只要四元数没用过就能建立新链接

TCP 三次握手过程是怎样的?

认为链接发起方是客户端。close状态的客户端发送带有序列号的syn报文,进入syn_sent状态;listen状态的服务端在接收到syn报文后进入syn_rcvd状态,向客户端发送带有随机新序列号和ack加一的syn_ack报文,客户端收到后进入establis状态并给服务端发送带有ack加一的ack报文,服务端接受到后进入establis状态

如何在 Linux 系统中查看 TCP 状态?

netstat -napt

为什么是三次握手?不是两次、四次?

四次的话冗余了,两次的话没法避免历史链接初始化,没法同步收发双方的序列号。

如果只是两次握手的话,服务端在接受到一个syn包就会直接进入全开队列。那么如果网络中有一个历史包的话,这个历史包就会使得服务端创建一个链接,造成资源浪费甚至阻止新链接生成。如果客户端实际没有发起连接的话,那这个链接就会被长期维护

如果没有同步序列号,那么服务器向客户端发送内容的时候,客户端就不知道从哪里开始,可能会导致开始的包丢失了也无法识别

为什么每次建立 TCP 连接时,初始化的序列号都要求不一样呢?

一是为了减少历史报文出现在接收窗口中的概率,二是为了防止黑客攻击。

初始序列号 ISN 是如何随机产生的?

伪随机。计时器给一个数;加源、目的的四元数生成一个哈希值。最后总和作为序列号

既然 IP 层会分片,为什么 TCP 层还需要 MSS 呢?

TCP一个包的长度可能是ip包装不下的,如果被分片的话一个ip包丢失,整个TCP包都要重传。,造成资源浪费

第一次握手丢失了,会发生什么?

过段时间重发,丢失超过一定的次数断开连接

第二次握手丢失了,会发生什么?

客户端会重发,服务端由于没有收到相应的ack,也会重发

第三次握手丢失了,会发生什么?

服务端重发syn_ack包(普通的ack包不会重传)。

什么是 SYN 攻击?如何避免 SYN 攻击?

黑客伪造大量的syn包发送给服务器,但是不返回ack包。挤满服务端的半开队列。

开tcp_syncookies参数,即使半开队列满了也能通过cookies识别ack包,直接进入全开队列。或者调大半开队列大小。或者减少ack重传次数。

TCP 四次挥手过程是怎样的?

假设客户端发起关闭链接请求。客户端发送FIN包,进入FIN_WAIT1状态。服务端接受到后返回ack包,进入close_wait状态。客户端收到ack包后进入FIN_WAIT2状态。服务端发送完数据之后发送FIN包,进入last_ack状态。客户端收到FIN包后进入time_wait状态,并返回ack包。客户端2msl后关闭,服务端收到ack包后关闭。

为什么挥手需要四次?

如果客户端没数据发送的话,三次也行(FIN和ack合为一个)

第一次挥手丢失了,会发生什么?

关闭发起者重传(下面都假定客户端发起关闭)

第二次挥手丢失了,会发生什么?

客户端重传FIN包

第三次挥手丢失了,会发生什么?

服务器重传FIN包

第四次挥手丢失了,会发生什么?

服务器重传FIN包,客户端2msl后关闭

close函数和shutdown函数

这两个函数都是操作系统提供给上层函数的。close是要关闭链接,释放资源。shutdown是部分关闭。如果关闭读方向,那么不再从这个socket中读取内容;如果是写方向,上层不再向这个socket中发送数据,但依然可以从这个socket中读取内容,此时会触发tcp的FIN,进入半关闭状态。

为什么 TIME_WAIT 等待的时间是 2MSL?

保证即使ack包丢失一次也可以正常关闭(会收到服务端发来的第二次FIN包并发送ack)

为什么需要 TIME_WAIT 状态?

帮助被动关闭一方可以被正常关闭。确保网络中的历史数据都消息,避免历史数据对链接产生影响。他属于是一个保底机制。

如何优化 TIME_WAIT?

如果链接频繁开启关闭,time_wait时间过长的话,启动reuseAddress参数,使得time_wait一秒后就可以直接建立新链接

作为服务端来讲,尽量不要主动关闭链接,这样的话关闭链接的time_wait就又客户端承担了。

服务器出现大量 TIME_WAIT 状态的原因有哪些?

根本原因都是主动断开了太多链接,有这么几种情况可以导致:

没有开启长连接。长连接超时(一般是服务端发起关闭链接)。HTTP请求过多(会关闭老的建立新的,那么老的就处于time_wait了)

服务器出现大量 CLOSE_WAIT 状态的原因有哪些?

说明没有调用close函数

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

tcp保活,7200秒后启动保活机制,开始发送FIN包尝试关闭。(一般时间是2小时11分15秒后连接关闭)。或者在HTTP层设置心跳机制,可以减少这个保活机制的时间

如果已经建立了连接,但是服务端的进程崩溃会发生什么?

进程崩溃不同于断电。崩溃时系统会自动调用函数完成连接关闭。

针对 TCP 应该如何 Socket 编程?

对于服务端来讲,需要新建socket,(socket实际上就是个文件描述符),绑定端口,监听端口。客户端新建socket后调用connect发起连接。服务端调用accept函数将链接从全开队列中取出并返回一个新的socket用于收发这个链接的数据

accept 发生在三次握手的哪一步?

第三次握手成功之后

没有 accept,能建立 TCP 连接吗?

能建立链接,但无法通信,accept只是将连接取出,tcp连接过程实际上是在全连接队伍中放入一个链接

没有 listen,能建立 TCP 连接吗?

可以自连接,如果同时发起也能创建链接

重传机制

超时重传和快速重传。超时重传指的是超过一个RTO之后没有报文回来。快速重传指的是连续收到三个相同的ack

SACK 方法

为了通知数据发送方在丢失报文时应该重传哪些内容,采用SACK。在报头的选项中启用SACK。SACK会储存从ack后接受到的所有报文的序列号的起始值和终止值。

Duplicate SACK

在SACK的基础上加上一个已经ack但重复接受的报文序列值。帮助发送方判断网络情况。

滑动窗口

 是TCP的一个机制,允许tcp无需获得应答,就可以发送新的报文。窗口的大小是动态的,由接收方缓存区可用大小和拥塞窗口大小共同决定决定。接收方通过ack报文头部中的窗口字段告知发送方当前窗口大小。收到新的ack后窗口起始点后移。窗口中有已经接受但并未ack的报文和未发送的报文。窗右边是已经ack的报文,左边是不能发送的报文

流量控制

指的就是TCP如何控制滑动窗口的大小。滑动窗口的大小应该等于接收方缓存区剩余可接受的的大小。并且为了避免由于缓存区大小整体减小导致的报文丢失,应该先减小窗口到调整缓冲区大小后可接收的大小,再减小缓冲区。

如果窗口大小为0的话,发送方会定时探测可用窗口大小,避免一直发送不了数据(死锁)。

为了避免糊涂窗口,会启用nagle算法并设置窗口的最小大小。nagle算法指的是小窗口情况下需要收到新的ack才会发送新的包

拥塞控制

强调一下上面提到的,滑动窗口大小等于拥塞窗口和接收方发来的窗口大小的较小值。

拥塞控制有:慢启动,拥塞避免。在发生重传时按照重传类型不同有拥塞发生和快速恢复两种算法

慢启动:在检测门限之前,拥塞窗口大小从1开始,每收到一个ack报文窗口就增加一。窗口大小随时间呈指数增长。到达门限之后进入拥塞避免状态。

拥塞避免:每收到一个ack报文拥塞窗口增加 1/拥塞窗长 个大小。窗扣大小随时间线性增长。

拥塞发生:此时一个RTO内没有收到报文(即发生超时重传),认为发生了严重的网络问题。直接窗口大小变为1,门限减半,重走慢启动等。

快速恢复:收到三个或以上的重复ack号报文(即发生快速重传)。门限变为窗长的一半,窗长也减半。然后进入快速恢复:由于已经收到了三个ack,所以窗长会加3,然后重发认为丢失的报文。之后每收到一个ack窗长加一。如果收到了新的ack,那么窗长变为门限,继续进行拥塞避免的步骤。

TCP粘包和拆包

TCP只负责传输字节流,换句话说就是TCP从缓冲区读数据然后发走,并不感知消息边界,不关心缓冲区中的内容具体是什么。这就会导致上层的消息可能会被TCP拆分或者整合,应用层无法分辨消息的边界。

解决办法就是加分隔符、加消息长度、固定消息长度等。

SYN 报文什么时候情况下会被丢弃?

半开队列和全开队列都满了

已建立连接的TCP,收到SYN会发生什么?

考虑的情况是客户端意外关闭,重新发起连接。服务端在收到syn后会返回服务端原本的ack号对应的ack报文,客户端收到这个报文后,由于前后不匹配,就会返回一个rst报文,然后重新发起连接

在 TIME_WAIT 状态,收到 RST 会断开连接吗?

看参数设置,有可能直接断开,也有可能丢弃rst

在 TIME_WAIT 状态的 TCP 连接,收到 SYN 后会发生什么?

如果是合法的syn就创建新链接,非法的就返回一个服务端的ack号,然后客户端会判断他非法,返回一个rst报文

keep-alive 与心跳机制的区别和用途

keep-alive是HTTP维护长连接用的。心跳机制可以使应用层自己实现的,更加灵活

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值