CPPInterview

计算机网络

为什么建立连接需要3次握手

粘包问题

udp不存在粘包的问题,因为udp是个数据包协议,也就是两段数据间有界限的。要么收不到,要么全收。

产生粘包的原因:nagle算法为了改善网络传输效率,延迟发送数据。应用层由于某些原因不能及时取出TCP的数据,导致TCP缓冲区存放了多段数据。

解决方式:封包和拆包。包头存放一个变量记录包体的长度。在所发送的内容前,加上发送内容的长度。

HTTP原理

http与https的区别

  1. 传输方式:http是明文传输,极易被监听和篡改。而https加入了ssl层,数据经过了加密,从而保护了传输数据的隐私和完整性。
  2. 身份认证: http没有身份认证,而https经过证书颁发机构的多重认证。
  3. 连接端口:http为80,https为443。
  4. 实现成本:http基本没有成本,https需要申请证书,同时在加密解密上需要消耗更多的CPU资源,访问速度有可能降低。
  5. 加锁的图标显示 谷歌和百度搜索的排名会对非https的排名有影响
    • 私钥能解密,但是不能确认是哪个客户端发送的消息,任何人都可以抵赖。为了防止抵赖,可以使用数字签名。
    • https是http的安全版,在http的基础上增加了SSL安全层。
    • 基于性能的考虑,https一般使用非对称加密算法获得密钥,再用对称加密算法对消息内容进行加密。 https发送请求的过程:
  6. 第一步,客户端和服务器端交换SSL版本和加密组件列表,同时服务器端将密钥和签名证书发给客户端。
  7. 第二步:客户端根据证书和密钥进行验证,通过以后协商传输的密钥。这一步使用非对称加密算法。
  8. 第三步:当双方都获得密钥,且校验码没有问题。则进行TCP三次握手,此时采用对称加密算法,提高效率。

http1.0 与 http1.1的区别

  1. 长连接:HTTP 1.1支持长连接和请求的流水线处理,在一个TCP连接上可以传送多个HTTP请求和响应,减少了建立和关闭连接的消耗和延迟。
  2. 带宽优化:HTTP/1.1中在请求消息中引入了range头域,它允许只请求资源的某个部分。
  3. 新增响应状态码:100 continue 已经收到第一部分,正等待剩余部分。 101 switch protocols 服务器已确认切换协议。
  4. host头域:允许物理主机上多个虚拟主机共享一个IP
  5. 缓存机制更灵活,新增control-cache头域
  6. 增加了5个请求方法:put delete connect options trace

get和post的区别

cookie和session

使用cookie来管理session以弥补http中无状态特性。通过对set-cookie头域写入session ID可以免登录,提高访问的效率。

握手优化:session缓存, session key 放在内存,有内存消耗, 负载均衡后找不session key。session ticket 集群可以共享。

TCP和UDP的区别

  1. TCP: 面向连接的安全的流式协议,连接的时候进行三次握手,数据发送的时候会进行数据确认,数据丢失之后,会进行数据重传。 确认和重传机制。
  2. UDP: 面向无连接的不安全的报文传输,发出去就不管了,收则全收,丢则全丢。

3次握手和4次挥手

TCP三次握手:客户端向服务器端:发送SYN=1和序号seq 服务器端向客户端:回应确定信号同意连接ACK=1以及自己的连接请求SYN=1还有序号seq 客户端回应服务器端:ACK=1告诉对方它已经知道了服务器端同意,连接成功。

TCP四次挥手:主动关闭方发送关闭信号,被动关闭方收到信号。然后进入半关闭状态,关闭的一方能接收数据但是不能发送数据。 等到另一个未关闭的一方,发起关闭信号以后,进入TIME_WAIT状态,等待对方2MSL之后,彻底关闭。

3次握手

4次挥手

拥塞窗口

慢启动 拥塞避免 快重传 快恢复

  1. 慢启动:为了防止大量数据瞬间注入网络,引起网络阻塞。慢启动算法设定,最开始窗口为1个最大报文长度。一个传输轮次增加一倍的窗口大小。当达到慢开始门限后,执行拥塞避免算法。
  2. 拥塞避免: 每个传输轮次将窗口增加一个单位,即加法增长。
  3. 快重传: 当收到3个重复确认以后,执行快恢复算法。慢开始门限和发送窗口减半,然后发缺失的数据,进行加法增长,重新进入拥塞避免阶段。
  4. 快恢复:慢开始门限减半,发送拥塞窗口设定为门限加3。如果后面依旧收到重复的ACK则进行加法增长窗口,如果收到新的ACK,则拥塞窗口设定为慢开始门限的值,并重新进入拥塞避免阶段。

超时进入的是慢启动,重复确认才进入快恢复。

选择性重传在options中left edge和right edge告诉发送方已经收到的报文序号

TCP粘包问题

udp不会出现粘包。发送方发送的若干包数据到接收方接收时,包粘在了一起。

造成粘包的原因时因为发送端延迟发送或者接收方没有及时接收缓冲区中的数据。

  1. 编程时设定立即发送的操作指令
  2. 把数据长度与消息一起发送。
  3. 使用特殊标记来区分消息的间隔

HTTP和HTTPS有什么不同

HTTP协议是一种使用明文数据传输的网络协议。HTTPS协议可以理解为HTTP协议的升级,就是在HTTP的基础上增加了数据加密。在数据进行传输之前,对数据进行加密,然后再发送到服务器。这样,就算数据被第三者所截获,但是由于数据是加密的,所以你的个人信息让然是安全的。这就是HTTP和HTTPS的最大区别。

在浏览器地址栏键入URL,按下回车之后会经历以下流程

  1. 浏览器向 DNS 服务器请求解析该 URL 中的域名所对应的 IP 地址;(递归式和迭代式)
  2. 解析出 IP 地址后,根据该 IP 地址和默认端口 80,和服务器建立TCP连接;
  3. 浏览器发出读取文件(URL 中域名后面部分对应的文件)的HTTP 请求,该请求报文作为 TCP 三次握手的第三个报文的数据发送给服务器;
  4. 服务器对浏览器请求作出响应,并把对应的 html 文本发送给浏览器;
  5. 释放 TCP连接;
  6. 浏览器将该 html 文本并显示内容;  

UDP如何做到可靠

NAT DNS ARP

  1. NAT用于实现从内部IP地址到外部IP地址的映射
  2. DNS提供域名到IP地址的映射或者反过来
  3. ARP提供IP到MAC地址的映射

DNS

基于UDP的协议

  1. 递归查询:父域名代替当前服务器递归查询,最后依次返回
  2. 迭代查询:父域名服务器告诉当前服务器下一次查询的位置

http状态码

  1. 100 continue 等待继续发送
  2. 200 ok 请求成功
  3. 206 partial content 部分资源
  4. 301 永久重定向
  5. 302 临时重定向 307
  6. 400 客户端请求报文语法错误
  7. 403 禁止访问
  8. 404 资源不存在
  9. 408 请求超时
  10. 500 服务器内部错误
  11. 503 服务器不可用

    http 2.0 SPDY

  12. 二进制分帧
  13. 多路复用
  14. 首部压缩
  15. 服务器推送

http 3.0 QUIC+UDP

  1. 0 RTT
  2. 没有队头阻塞的多路复用
  3. 前向纠错

网络安全

  1. sql注入:用户提交一段数据库查询代码,根据程序返回的结果获得它想得知的数据。
  2. dos攻击: 让运行的服务器呈停止状态。集中请求造成资源过载,攻击安全漏洞使服务停止。

    七层模型

    物数网传会表应 ping是从应用层直接使用网络层的ICMP协议的,不经过传输层。原始套接字直接使用网络层的IP。 两台电脑通信:网线+不同的IP地址和子网掩码,即处于同一网段。 TCP和UDP可以同时使用相同的端口。 应用程序可以同时使用TCP和UDP两个协议。

    hub集线器

可以实现多个IP主机通信,但是hub的实现方式是广播,容易产生拥堵。

switch交换机

是集线器的升级版,可以广播可单播。ARP不知道对方MAC地址时,先广播6个ff的MAC地址,所有网卡都会接收,但是只有目的IP会单播回应,其他的都会丢弃。然后发送方收到正确的MAC后再单播传输数据。

ARP攻击

给两个MAC地址响应ARP广播的目的IP,经由中间人,窃取信息后再转发到正确的地址。

默认网关

在同一个交换机连接的网络中,属于同一网段,用不到默认网关。网关用来传递两个不同网段的通信,默认网关通常是路由器。当通信的数据不在当前网段时,即发给默认网关。路由器就是用来连接不同网段的,用来构建一个更大的网络。在传输不同的网段信息时,源IP和目的IP是不变的,源MAC和目的MAC是改变的,每经过一个路由器修改一次,记录的是下一次的目的,和这一次的发送MAC。

延迟确认

ack会随着响应数据发送给对方,如果没有响应的数据就会等待200ms左右,在这期间如果有对方确认到达则立即发送。如果200ms后仍然没有数据需要发送则单独发送ACK。目的是节省带宽。

Nagle算法

  1. 没有已发送未确认报文段时,立即发送数据。
  2. 存在未确认报文段时,达到mss时再发。

同时有nagle算法和延迟确认存在时会导致网络效率下降,通常会关闭延迟确认和nagle算法。

setsockopt(s,IPPROTO_TCP,TCP_QUICKACK,(int*){1}, sizeof(int)); //关闭延迟确认
setsockopt(client_fd, SOL_TCP, TCP_NODELAY,(int[]){1}, sizeof(int)); //关闭nagle算法

忽略SIGPIPE信号

signal(SIGPIPE, SIG_IGN)

SIGSEGV 11 访问地址无效 SIGIO 29异步通知信号 SIGKILL 9 无条件终止

传输层与网络层的区别

  1. 传输层位于网络层之上,为不同主机上的应用进程提供逻辑通信。端到端传输
  2. 网络层负责ip数据报的产生以及ip数据包在网络中的路由转发

状态码499

服务器端处理的时间过长,客户端主动关闭了连接。

分块编码

transfer-encoding:chunked 响应头域 它允许服务器发送给客户端的数据分成多个部分,并且不需要预先直到发送数据的总大小。

close_wait

301 move permanently

302 found POST方法的重定向在未询问用户的情况下就变成GET

303 see other POST重定向为GET

307 temporary redirect 当客户端的POST请求收到服务端307状态码响应时,需要跟用户询问是否应该在新URI上发起POST方法,也就是说,307是不会把POST转为GET的。

TCP拥塞控制

TCP状态转换

http2.0和http3.0

http2.0 spdy

流量控制和拥塞控制

实现机制:由滑动窗口协议(连续ARQ协议)实现。滑动窗口协议既保证了分组无差错、有序接收,也实现了流量控制。主要的方式就是接收方返回的 ACK 中会包含自己的接收窗口的大小,并且利用大小来控制发送方的数据发送

可能会引发死锁,怎么避免:当发送者收到了一个窗口为0的应答,发送者便停止发送,等待接收者的下一个应答。但是如果这个窗口不为0的应答在传输过程丢失,发送者一直等待下去,而接收者以为发送者已经收到该应答,等待接收新数据,这样双方就相互等待,从而产生死锁。为了避免流量控制引发的死锁,TCP使用了持续计时器。每当发送者收到一个零窗口的应答后就启动该计时器。时间一到便主动发送报文询问接收者的窗口大小。若接收者仍然返回零窗口,则重置该计时器继续等待;若窗口不为0,则表示应答报文丢失了,此时重置发送窗口后开始发送,这样就避免了死锁的产生。

流量控制与拥塞控制的区别

拥塞控制:拥塞控制是作用于网络的,它是防止过多的数据注入到网络中,避免出现网络负载过大的情况;常用的方法就是:

  1. 慢开始、拥塞避免
  2. 快重传、快恢复。

流量控制:流量控制是作用于接收者的,它是控制发送者的发送速度从而使接收者来得及接收,防止分组丢失的。

拥塞控制算法

假定:1、数据是单方向传递,另一个窗口只发送确认;2、接收方的缓存足够大,因此发送方的大小的大小由网络的拥塞程度来决定。

  1. 慢开始算法

发送方维持一个叫做拥塞窗口cwnd(congestion window)的状态变量。拥塞窗口的大小取决于网络的拥塞程度,并且动态地在变化。发送方让自己的发送窗口等于拥塞窗口,另外考虑到接受方的接收能力,发送窗口可能小于拥塞窗口。

慢开始算法的思路就是,不要一开始就发送大量的数据,先探测一下网络的拥塞程度,也就是说由小到大逐渐增加拥塞窗口的大小

这里用报文段的个数作为拥塞窗口的大小举例说明慢开始算法,实际的拥塞窗口大小是以字节为单位的。如下图:

从上图可以看到,一个传输轮次所经历的时间其实就是往返时间RTT,而且没经过一个传输轮次(transmission round),拥塞窗口cwnd就加倍。

为了防止cwnd增长过大引起网络拥塞,还需设置一个慢开始门限ssthresh状态变量。ssthresh的用法如下:当cwnd < ssthresh时,使用慢开始算法。

  1. 当cwnd>ssthresh时,改用拥塞避免算法。
  2. 当cwnd=ssthresh时,慢开始与拥塞避免算法任意

注意,这里的“慢”并不是指cwnd的增长速率慢,而是指在TCP开始发送报文段时先设置cwnd=1,然后逐渐增大,这当然比按照大的cwnd一下子把许多报文段突然注入到网络中要“慢得多”。

  1. 拥塞避免算法

拥塞避免算法让拥塞窗口缓慢增长,即每经过一个往返时间RTT就把发送方的拥塞窗口cwnd加1,而不是加倍。这样拥塞窗口按线性规律缓慢增长。

无论是在慢开始阶段还是在拥塞避免阶段,只要发送方判断网络出现拥塞(其根据就是没有按时收到确认,虽然没有收到确认可能是其他原因的分组丢失,但是因为无法判定,所以都当做拥塞来处理),就把慢开始门限ssthresh设置为出现拥塞时的发送窗口大小的一半(但不能小于2)。然后把拥塞窗口cwnd重新设置为1,执行慢开始算法。这样做的目的就是要迅速减少主机发送到网络中的分组数,使得发生拥塞的路由器有足够时间把队列中积压的分组处理完毕

  1. 快重传算法

快重传要求接收方在收到一个失序的报文段后就立即发出重复确认(为的是使发送方及早知道有报文段没有到达对方,可提高网络吞吐量约20%)而不要等到自己发送数据时捎带确认。快重传算法规定,发送方只要一连收到三个重复确认就应当立即重传对方尚未收到的报文段,而不必继续等待设置的重传计时器时间到期

  1. 快恢复算法

http和https的区别

https是安全版的http协议。

get和post的区别

get用来获取资源,post用来创建资源。

get将数据放在url地址栏中,使用问号与url分割,数据间用取地址符分割。post将数据放在请求体中。

安全性上get放在url容易暴露隐私信息,而post放在请求体中可以适当的避免。

get在传输的数据受url地址栏的限制,post不受这种限制

get的操作是幂等的,多次操作产生的影响相同,而post是非幂等的

断点续传

视频辅助

  1. 客户端在header中的range字段中指明,请求传输的区间[l, r]
  2. 服务器端在header中的content-range返回当前接受的范围和文件总大小。并返回206patial content 状态码。

TLS协议

视频

TLS握手协议:1.交换加解密的安全套件 2.验证通讯双方的身份 3.协商加密的参数。

https是在TCP之上增加了一层TLS层

TLS1.3版本限定了安全套件的数量,防止低版本的安全组件被暴力破解。开始时客户端发送hello并携带一个自己生成的公钥,服务器端选择一个安全套件并将自己生成的公钥发给客户端,客户端收到公钥以后,两段此时都有一个对方发来的公钥和自己的私钥。此时使用ECDH椭圆曲线非对称加密算法,生成一个相同的密钥,这个密钥就用来进行后续的对称加密。

校验过程:判断数字证书中的哈希值和公钥解码的哈希值是否一致。

TCP两次握手会产生什么问题

参考链接

长期处于半连接状态可能会造成TCP内核中SYN队列的爆满,服务器会在一定时间内终止半连接,并回收资源。如果使用syn洪泛攻击,也可能造成SYN队列爆满,可以使用SYN cookie来解决这个问题。即SYN到达时并不放入SYN队列中,而是将所有的信息写入cookie,当客户端ACK到达时验证cookie中的信息后再分配资源。

TCP两次握手会产生什么问题:已经失效的连接报文段突然又被服务器端收到,造成双方的不一致,进而造成资源浪费。此时如果服务器端发送连接到失效的请求,并返回SYN和ACK后,自认为连接已经建立好了,所以会频繁的发送数据到客户端,而客户端处于closed状态,直接把数据丢弃。同时如果此时客户端想要建立新连接,但是已经又连接占用,也会导致客户端无法建立真正的需求。当客户端老是收到丢弃的数据,客户端就会发一个RST强制服务端关闭连接。

RST和ACK收到时不用再回ACK

DNS污染

http协议

http协议用韵都是客户端发起请求,服务器返回响应,这样就会使得无法实现客户端未发起的请求,而服务器将消息推送给客户端。

请求报文组成部分:1. 请求行 2.请求头 3. 请求空行 4. 请求体

http在1.1版本中,所有的请求头除host外都是可选的。host主要用于指定被请求资源的Internet主机和端口号,它通常从HTTP的URL中提取出来的。不包含host主机头域,服务器会返回400状态码。

1xx: 提示信息,表示请求已接收,继续处理。

2xx: 成功, 表示请求已被成功接收,理解,接受。

3xx: 重定向, 要完成请求必须进行更进一步的操作。

4xx: 客户端错误,请求有语法错误或请求无法实现。

5xx: 服务器错误,服务器未能实现合法的请求。

ssl通信机制:1. 客户端发送client hello报文开始通信。报文中包含SSL指定版本号,加密组件列表,有加密算法和密钥长度。2. 服务器端回应server hello报文作为应答。筛选出SSL版本和加密组件,并发送CA证书,其中包括公钥。3. 第二次交互,客户端生成一个pre-master secret的随机密码串。并使用CA证书中的公钥加密。

http和https的区别

主要区别在于:

  1. http是明文传输,https是密文传输。
  2. http默认端口是80, https的默认443
  3. https需要验证服务器端的身份,如果CA证书不正确则会中断通信。
  4. CA证书需要成本,加密解密的过程增加CPU和内存的开销。