美文网首页
网络协议

网络协议

作者: Impossible安徒生 | 来源:发表于2020-04-09 17:22 被阅读0次

    网络协议

    1. 服务器输入url到返回页面的全过程(俗称天龙八步)

      • 1.根据域名,进行DNS域名解析;

        我们在浏览器输入网址,其实就是要向服务器请求我们想要的页面内容,所有浏览器首先要确认的是域名所对应的服务器在哪里。将域名解析成对应的服务器IP地址这项工作,是由DNS服务器来完成的。

        客户端收到你输入的域名地址后,它首先去找本地的hosts文件,检查在该文件中是否有相应的域名、IP对应关系,如果有,则向其IP地址发送请求,如果没有,再去找DNS服务器。一般用户很少去编辑修改hosts文件。

      • 2.拿到解析的IP地址,建立TCP连接;

        费了一顿周折终于拿到服务器IP了,下一步自然就是链接到该服务器。对于客户端与服务器的TCP链接,必然要说的就是『三次握手』。

        <img src="https://user-gold-cdn.xitu.io/2017/11/20/15fd7aab5ef0ab84?imageslim" alt="img" style="zoom:50%;" />

        客户端发送一个带有SYN标志的数据包给服务端,服务端收到后,回传一个带有SYN/ACK标志的数据包以示传达确认信息,最后客户端再回传一个带ACK标志的数据包,代表握手结束,连接成功。

        上图也可以这么理解:

        客户端:“你好,在家不,有你快递。”

        服务端:“在的,送来就行。”

        客户端:“好嘞。”

      • 3.向IP地址,发送HTTP请求;

        与服务器建立了连接后,就可以向服务器发起请求了。

        <img src="https://user-gold-cdn.xitu.io/2017/11/20/15fd7aab5edfbd5b?imageslim" alt="img" style="zoom:50%;" />

        请求行包括请求方法、URI、HTTP版本。首部字段传递重要信息,包括请求首部字段、通用首部字段和实体首部字段。我们可以从报文中看到发出的请求的具体信息。具体每个首部字段的作用,这里不做过多阐述。

      • 4.服务器处理请求;

        服务器端收到请求后的由web服务器(准确说应该是http服务器)处理请求,诸如Apache、Ngnix、IIS等。web服务器解析用户请求,知道了需要调度哪些资源文件,再通过相应的这些资源文件处理用户请求和参数,并调用数据库信息,最后将结果通过web服务器返回给浏览器客户端。

        <img src="https://user-gold-cdn.xitu.io/2017/11/20/15fd7aab7ec68a75?imageslim" alt="img" style="zoom:50%;" />

      • 5.返回响应结果;

        在HTTP里,有请求就会有响应,哪怕是错误信息。在响应结果中都会有个一个HTTP状态码,比如我们熟知的200、301、404、500等。通过这个状态码我们可以知道服务器端的处理是否正常,并能了解具体的错误。

        <img src="https://user-gold-cdn.xitu.io/2017/11/20/15fd7aab87da17f8?imageslim" alt="img" style="zoom:80%;" />

      • 6.关闭TCP连接;

        为了避免服务器与客户端双方的资源占用和损耗,当双方没有请求或响应传递时,任意一方都可以发起关闭请求。与创建TCP连接的3次握手类似,关闭TCP连接,需要4次握手。

        <img src="https://user-gold-cdn.xitu.io/2017/11/20/15fd7aab945db09e?imageslim" alt="img" style="zoom:67%;" />

        上图可以这么理解:

        客户端:“兄弟,我这边没数据要传了,咱关闭连接吧。”

        服务端:“收到,我看看我这边有木有数据了。”

        服务端:“兄弟,我这边也没数据要传你了,咱可以关闭连接了。”

        客户端:“好嘞。”

      • 7.浏览器解析HTML;

      • 8.浏览器布局渲染;

    2. DNS 是什么?DNS 的查询过程?怎么减少DNS的传输时间

      • DNS 主要的作用就是将人们所熟悉的网址 (域名) “翻译”成电脑可以理解的 IP 地址,这个过程叫做 DNS 域名解析。

      • 域名的结构

        • www.tmall.com对应的真正的域名为www.tmall.com.。末尾的.称为根域名,因为每个域名都有根域名,因此我们通常省略。

        • 根域名的下一级,叫做"顶级域名"(top-level domain,缩写为TLD),比如.com、.net;

        • 再下一级叫做"次级域名"(second-level domain,缩写为SLD),比如www.tmall.com里面的.tmall,这一级域名是用户可以注册的;

        • 再下一级是主机名(host),比如www.tmall.com里面的www,又称为"三级域名",这是用户在自己的域里面为服务器分配的名称,是用户可以任意分配的。

      • DNS查询过程

        (1)先在本机的DNS里头查,如果有就直接返回了。

        (2)本机DNS里头发现没有,就去根服务器里查。根服务器发现这个域名是属于com域,,因此根域DNS服务器会返回它所管理的com域中的DNS 服务器的IP地址,意思是“虽然我不知道你要查的那个域名的地址,但你可以去com域问问看”

        (3)本机的DNS接到又会向com域的DNS服务器发送查询消息。com 域中也没有www.tmall.com这个域名的信息,和刚才一样,com域服务器会返回它下面的tmall.com域的DNS服务器的IP地址。

    3. 一个 TCP 连接上面能发多少个 HTTP 请求

      • 一个 TCP 连接可以对应几个 HTTP 请求?

      在 HTTP/1.0 中,一个服务器在发送完一个 HTTP 响应后,会断开 TCP 链接。但是这样每次请求都会重新建立和断开 TCP 连接,代价过大。所以虽然标准中没有设定,某些服务器对 Connection: keep-alive 的 Header 进行了支持。意思是说,完成这个 HTTP 请求之后,不要断开 HTTP 请求使用的 TCP 连接。这样的好处是连接可以被重新使用,之后发送 HTTP 请求的时候不需要重新建立 TCP 连接,以及如果维持连接,那么 SSL 的开销也可以避免。

    HTTP/1.1 就把 Connection 头写进标准,并且默认开启持久连接,除非请求中写明 Connection: close,那么浏览器和服务器之间是会维持一段时间的 TCP 连接,不会一个请求结束就断掉。

    • 一个 TCP 连接中 HTTP 请求发送可以一起发送么?

    HTTP/1.1 存在一个问题,单个 TCP 连接在同一时刻只能处理一个请求,意思是说:两个请求的生命周期不能重叠,任意两个 HTTP 请求从开始到结束的时间在同一个 TCP 连接里不能重叠。但是,HTTP2 提供了 Multiplexing 多路传输特性,可以在一个 TCP 连接中同时完成多个 HTTP 请求。

    在 HTTP/1.1 存在 Pipelining 技术可以完成这个多个请求同时发送,但是由于浏览器默认关闭,所以可以认为这是不可行的。在 HTTP2 中由于 Multiplexing 特点的存在,多个 HTTP 请求可以在同一个 TCP 连接中并行进行。

    • 浏览器对同一 Host 建立 TCP 连接到数量有没有限制?

    有。Chrome 最多允许对同一个 Host 建立六个 TCP 连接。不同的浏览器有一些区别。

    • 收到的 HTML 如果包含几十个图片标签,这些图片是以什么方式、什么顺序、建立了多少连接、使用什么协议被下载下来的呢?

    如果图片都是 HTTPS 连接并且在同一个域名下,那么浏览器在 SSL 握手之后会和服务器商量能不能用 HTTP2,如果能的话就使用 Multiplexing 功能在这个连接上进行多路传输。不过也未必会所有挂在这个域名的资源都会使用一个 TCP 连接去获取,但是可以确定的是 Multiplexing 很可能会被用到。

    如果发现用不了 HTTP2 呢?或者用不了 HTTPS(现实中的 HTTP2 都是在 HTTPS 上实现的,所以也就是只能使用 HTTP/1.1)。那浏览器就会在一个 HOST 上建立多个 TCP 连接,连接数量的最大限制取决于浏览器设置,这些连接会在空闲的时候被浏览器用来发送新的请求,如果所有的连接都正在发送请求呢?那其他的请求就只能等等了。

    1. RPC相对于传统的API调用的优点

      • RPC

      RPC 采用客户端—服务器(Client/Server)的工作模式。请求程序就是一个客户端(Client), 而服务提供程序就是一个服务器(Server)。当执行一个远程过程调用时,客户端程序首先发送一 个带有参数的调用信息到服务端,然后等待服务端响应。在服务端,服务进程保持睡眠状态直到 客户端的调用信息到达为止。当一个调用信息到达时,服务端获得进程参数,计算出结果,并向 客户端发送应答信息,然后等待下一个调用。最后,客户端接收来自服务端的应答信息,获得进 程结果,然后调用执行并继续进行。

      • RPC与HTTP
        • 用信息占比少,毕竟HTTP工作在第七层,包含了大量的HTTP头等信息。
        • 效率低,还是因为第七层的缘故。
        • 可读性似乎没有必要,因为我们可以引入网关增加可读性。
        • 使用HTTP协议调用远程方法比较复杂,要封装各种参数名和参数值。
    2. UDP和TCP

      • udp和tcp 流式传输和数据包传输区别体现在哪。

      结合TCP的概念,水池就好比接收缓存,倒水就相当于发送数据,接水就相当于读取数据。好比你通过TCP连接给另一端发送数据,你只调用了一次 write,发送了100个字节,但是对方可以分10次收完,每次10个字节;你也可以调用10次write,每次10个字节,但是对方可以一次就收完。 (假设数据都能到达)但是,你发送的数据量不能大于对方的接收缓存(流量控制),如果你硬是要发送过量数据,则对方的缓存满了就会把多出的数据丢弃。

      UDP和TCP不同,发送端调用了几次write,接收端必须用相同次数的read读完。UPD是基于报文的,在接收的时候,每次最多只能读取一个 报文,报文和报文是不会合并的,如果缓冲区小于报文长度,则多出的部分会被丢弃。也就说,如果不指定MSG_PEEK标志,每次读取操作将消耗一个报文。

      • TCP比UDP多消耗哪些系统资源?

        • TCP建立连接时三次握手,断开连接时四次挥手;

        • TCP数据包头部20字节,UDP数据包头部8字节;

        • TCP有流量控制和拥塞控制。

      • TCP和UDP区别

        • 1 基于连接和无连接;
        • 2 TCP是可靠,保证数据正确;UDP不可靠,不保证数据正确;
        • 3 TCP保证数据顺序到达;UDP不保证数据顺序到达;
        • 4 TCP速度慢,因为TCP必须创建连接;UDP速度较快,不需要建立连接;
        • 5 因为上述开销,TCP是一个重量级协议;UDP是一个轻量级的协议;
        • 6 一个TCP数据包报头的大小是20字节;一个UDP数据报报头是8个字节;
        • 7 TCP有流量控制和拥塞控制;UDP不能进行流量控制;
        • 8 TCP面向字节流;UDP面向报文;
    3. TCP为什么可靠

      tcp有个以字节为单位的滑动窗口,它把要发送的数据都以字节形式存储在这个滑动窗口当中。每次发送完窗口的数据后,都会先保留数据,只有当收到对方的数据确认收到信号时再清除这些数据,如果超时没有收到确认信号的话就要重传。这就是tcp的确认重传机制。

      主要是利用了tcp首部的各个信号位。确认最后一个到达的字符的序号。所以udp相比之下容易丢包,报文乱序。

    4. TCP为什么四次挥手

      • 因为TCP是全双工通信的。

      (1)第一次挥手

      ​ 因此当主动方发送断开连接的请求(即FIN报文)给被动方时,仅仅代表主动方不会再发送数据报文了,但主动方仍可以接收数据报文。

      ​ (2)第二次挥手

      ​ 被动方此时有可能还有相应的数据报文需要发送,因此需要先发送ACK报文,告知主动方“我知道你想断开连接的请求了”。这样主动方便不会因为没有收到应答而继续发送断开连接的请求(即FIN报文)。

      (3)第三次挥手

      ​ 被动方在处理完数据报文后,便发送给主动方FIN报文;这样可以保证数据通信正常可靠地完成。发送完FIN报文后,被动方进入LAST_ACK阶段(超时等待)。

      (4)第四挥手

      ​ 如果主动方及时发送ACK报文进行连接中断的确认,这时被动方就直接释放连接,进入可用状态。

      • 为什么time­_wait

      (1)A不能保证最后的ACK能达到B,如果最后的ACK丢失, 那么B显然收不到, B于是发起了重传FIN的操作, 此时如果A处于CLOSED的状态, 就没办法给对端发ACK了,所以A应该等一段时间,这段时间就是所谓的TIME_WAIT。

      (2)保证新旧四元组互不干扰,假设tcp连接是:A(1.2.3.4:8888)------B(6.7.8.9:9999), 这就是一个tcp四元组。 当tcp连接关闭后, 四元组释放。 后面的新连接可能会重用到这个四元组(有这个可能性), 那么问题就来了: 新四元组和旧四元组完全一致, 他们的网络包会混乱吗?所以,可以考虑这样一个机制:让旧四元组对应的所有网络包都消失后(等一段时间),才允许新四元组建立,颇有点锁的味道。这个等一段时间就是2MSL。

      • 连接过程中客户端和服务器都处于什么状态
        1. 客户端进程发出连接释放报文,并且停止发送数据。释放数据报文首部,FIN=1,其序列号为seq=u(等于前面已经传送过来的数据的最后一个字节的序号加1),此时,客户端进入FIN-WAIT-1(终止等待1)状态。 TCP规定,FIN报文段即使不携带数据,也要消耗一个序号。
        2. 服务器收到连接释放报文,发出确认报文,ACK=1,ack=u+1,并且带上自己的序列号seq=v,此时,服务端就进入了CLOSE-WAIT(关闭等待)状态。TCP服务器通知高层的应用进程,客户端向服务器的方向就释放了,这时候处于半关闭状态,即客户端已经没有数据要发送了,但是服务器若发送数据,客户端依然要接受。这个状态还要持续一段时间,也就是整个CLOSE-WAIT状态持续的时间。
        3. 客户端收到服务器的确认请求后,此时,客户端就进入FIN-WAIT-2(终止等待2)状态,等待服务器发送连接释放报文(在这之前还需要接受服务器发送的最后的数据)。
        4. 服务器将最后的数据发送完毕后,就向客户端发送连接释放报文,FIN=1,ack=u+1,由于在半关闭状态,服务器很可能又发送了一些数据,假定此时的序列号为seq=w,此时,服务器就进入了LAST-ACK(最后确认)状态,等待客户端的确认。
        5. 客户端收到服务器的连接释放报文后,必须发出确认,ACK=1,ack=w+1,而自己的序列号是seq=u+1,此时,客户端就进入了TIME-WAIT(时间等待)状态。注意此时TCP连接还没有释放,必须经过2∗*∗MSL(最长报文段寿命)的时间后,当客户端撤销相应的TCB后,才进入CLOSED状态。
        6. 服务器只要收到了客户端发出的确认,立即进入CLOSED状态。同样,撤销TCB后,就结束了这次的TCP连接。可以看到,服务器结束TCP连接的时间要比客户端早一些。
          <img src="https://img-blog.csdn.net/20170606084851272?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcXpjc3U=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="img" style="zoom:50%;" />
    5. TCP 的三次握手改成两次握手可以吗?

      不可以,一句话,主要防止已经失效的连接请求报文突然又传送到了服务器,从而产生错误。

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

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

      • 连接过程中客户端和服务器都处于什么状态。

        1. CP服务器进程先创建传输控制块TCB,时刻准备接受客户进程的连接请求,此时服务器就进入了LISTEN(监听)状态;
        2. TCP客户进程也是先创建传输控制块TCB,然后向服务器发出连接请求报文,这是报文首部中的同部位SYN=1,同时选择一个初始序列号 seq=x ,此时,TCP客户端进程进入了 SYN-SENT(同步已发送状态)状态。TCP规定,SYN报文段(SYN=1的报文段)不能携带数据,但需要消耗掉一个序号。
        3. TCP服务器收到请求报文后,如果同意连接,则发出确认报文。确认报文中应该 ACK=1,SYN=1,确认号是ack=x+1,同时也要为自己初始化一个序列号 seq=y,此时,TCP服务器进程进入了SYN-RCVD(同步收到)状态。这个报文也不能携带数据,但是同样要消耗一个序号。
        4. TCP客户进程收到确认后,还要向服务器给出确认。确认报文的ACK=1,ack=y+1,自己的序列号seq=x+1,此时,TCP连接建立,客户端进入ESTABLISHED(已建立连接)状态。TCP规定,ACK报文段可以携带数据,但是如果不携带数据则不消耗序号。
        5. 当服务器收到客户端的确认后也进入ESTABLISHED状态,此后双方就可以开始通信了。
     <img src="/Users/anyao/Library/Application Support/typora-user-images/image-20200403164645409.png" alt="image-20200403164645409" style="zoom:30%;" />
    
    • 第二次握手后没有回复会怎么样。

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

    1. WebSocket

      因为 HTTP 协议有一个缺陷:通信只能由客户端发起。只能是客户端向服务器发出请求,服务器返回查询结果。这种单向请求的特点,注定了如果服务器有连续的状态变化,客户端要获知就非常麻烦。我们只能使用"轮询":每隔一段时候,就发出一个询问,了解服务器有没有新的信息。最典型的场景就是聊天室。

      它的最大特点就是,服务器可以主动向客户端推送信息,客户端也可以主动向服务器发送信息,是真正的双向平等对话,属于服务器推送技术的一种。

      其他特点包括:

      (1)建立在 TCP 协议之上,服务器端的实现比较容易。

      (2)与 HTTP 协议有着良好的兼容性。默认端口也是80和443,并且握手阶段采用 HTTP 协议,因此握手时不容易屏蔽,能通过各种 HTTP 代理服务器。

      (3)数据格式比较轻量,性能开销小,通信高效。

      (4)可以发送文本,也可以发送二进制数据。

      (5)没有同源限制,客户端可以与任意服务器通信。

      (6)协议标识符是ws(如果加密,则为wss),服务器网址就是 URL。

    2. HTTP 请求常用的首部有哪些

    在请求中,HTTP报文由方法、URI、HTTP版本、HTTP首部字段等部分构成。在响应中,HTTP报文由HTTP版本、状态码(数字和原因短语)、HTTP首部字段3部分构成。

    协议头 说明
    Accept 可接受的响应内容类型(Content-Types)。
    Accept-Charset 可接受的字符集
    Cache-Control 用来指定当前的请求/回复中的,是否使用缓存机制。
    Cookie 由之前服务器通过Set-Cookie(见下文)设置的一个HTTP协议Cookie
    Content-Type 请求体的MIME类型 (用于POST和PUT请求中)
    Date 发送该消息的日期和时间(以RFC 7231中定义的”HTTP日期”格式来发送)
    Host 表示服务器的域名以及服务器所监听的端口号。
    If-Modified-Since 允许在对应的资源未被修改的情况下返回304未修改
    If-None-Match 允许在对应的内容未被修改的情况下返回 304 Not Modified
    Pragma 与具体的实现相关,这些字段可能在请求/回应链中的任何时候产生。
    User-Agent 浏览器的身份标识字符串
    1. 常见的 HTTP 状态码

      分类 分类描述
      1XX 信息,服务器收到请求,需要请求者继续执行操作
      2XX 成功,操作被成功接收并处理
      3XX 重定向,需要进一步的操作以完成请求
      4XX 客户端错误,请求包含语法错误或无法完成请求
      5XX 服务器错误,服务器在处理请求的过程中发生了错误
      • 301和302区别:

      301重定向是永久的重定向,搜索引擎在抓取新内容的同时也将旧的网址替换为重定向之后的网址。

      302重定向是临时的重定向,搜索引擎会抓取新的内容而保留旧的网址。

      • 502, 503和504的区别

      502

      灾难事件: 在某个连着两天的早晨9:00 左右,我们的服务器不幸挂掉了,影响了一批用户上班(早上着急上班骑不了自行车了,/捂脸)。当时打开我们的app和公司内部系统,报错都是502。

      问题原因:服务器冷不丁坏掉了

      解释:出现502错误,通常意味着一两个机器已经不正确,简单点说,就是机器挂掉了。理论点儿说,nginx执行请求的时候,却收到了上游服务器的无效响应

      503

      灾难事件:临时的服务器维护/过载,服务器当前无法处理请求,报503

      问题原因:请求用户量太多,服务器为了保护自己不挂掉,机智的拒绝某些用户的访问,这些用户就会收到503这个错误

      解决办法: 等一会儿仔访问该网站或者尝试强刷新页面,问题一般就能够解决了。

      504

      事件描述:dns查询过程超时,返回504;摸不着头脑,不管访问什么网站,都报504这个错误

      问题原因:nginx或者后端配置不正确

      解决办法:上网查nginx或后端的配置参数是否正确或者合理

      解释: 实际上504很少会遇到,通常这个错误是由于nginx配置不当引起的,比如你将你的nginx的超时时间设

      置为300,那么如果此次请求的响应时间超过了300,你就会看到504这个报错。明白了吧。官方说法:请求超时

      <img src="https://segmentfault.com/img/bV3Isu?w=660&h=833" alt="图片描述" style="zoom:60%;" />

    2. 5XX状态码

      500 Internal Server Error 服务器内部错误,无法完成请求
      501 Not Implemented 服务器不支持请求的功能,无法完成请求
      502 Bad Gateway 作为网关或者代理工作的服务器尝试执行请求时,从远程服务器接收到了一个无效的响应
      503 Service Unavailable 由于超载或系统维护,服务器暂时的无法处理客户端的请求。延时的长度可包含在服务器的Retry-After头信息中
      504 Gateway Time-out 充当网关或代理的服务器,未及时从远端服务器获取请求
      505 HTTP Version not supported 服务器不支持请求的HTTP协议的版本,无法完成处理
    3. Cookie Session区别

      本来 session 是一个抽象概念,开发者为了实现中断和继续等操作,将 user agent 和 server 之间一对一的交互,抽象为“会话”,进而衍生出“会话状态”,也就是 session 的概念。

      而 cookie 是一个实际存在的东西,http 协议中定义在 header 中的字段。可以认为是 session 的一种后端无状态实现。

      而我们今天常说的 “session”,是为了绕开 cookie 的各种限制,通常借助 cookie 本身和后端存储实现的,一种更高级的会话状态实现。

      1,session 在服务器端,cookie 在客户端(浏览器)

      2,session 默认被存在在服务器的一个文件里(不是内存)

      3,session 的运行依赖 session id,而 session id 是存在 cookie 中的,也就是说,如果浏览器禁用了 cookie ,同时 session 也会失效(但是可以通过其它方式实现,比如在 url 中传递 session_id)

      4,session 可以放在 文件、数据库、或内存中都可以。

      5,用户验证这种场合一般会用 session。

    因此,维持一个会话的核心就是客户端的唯一标识,即 session id [网络协议.md](网络协议.md) 
    
    1. 为什么基于TCP的HTTP是无状态呢?

      首先TCP是有状态的,在一次TCP连接之中,每一次的数据交换都和上一次紧密相关的,TCP报文存在ACK字段用于确认上次接收的报文,并且TCP在建立连接时交换了很多的连接配置信息,例如收、发缓存大小,报文序号等。所以,每一次TCP数据交换两方都是能够确切知道对方的信息的。

    因为HTTP是短连接,即每次“请求-响应”都是一次TCP连接。比如用户一次请求就是一次TCP连接,服务器响应结束后断开连接。而每次TCP连接是没有关联的,因此HTTP是无状态的。如果想要使得每次TCP连接之间有关联,服务器和浏览器就得存储相关的信息,这个就是Cookie和Session的作用。 
    
    1. osi七层模型,tcp/ip四层模型

      • osi七层模型:
      1. 物理层:建立、维护、断开物理连接
      2. 数据链路层:建立逻辑连接,进行硬件地址寻址、差错校验等功能
      3. 网络层:进行逻辑地址寻址,实现不同网络之间的路径选择
      4. 传输层:定义传输数据的协议端口号,以及流控和差错校验。eg. TCP、UDP,数据包一旦离开网卡即进入网络传输层
      5. 会话层:建立、管理、终止会话
      6. 表示层:数据的表示、安全、压缩 应用层:网络服务与最终用户的一个接口。eg. HTTP、FTP、SMTP
      7. 应用层:网络服务与最终用户的一个接口。eg. HTTP、FTP、SMTP
      • tcp/ip四层模型:链路层、网络层、传输层、应用层。
    2. 数据链路层详细介绍

      数据链路层是处于物理层和网络层之间,依靠着物理层给网络层提供服务。物理层中是把电压的高低或者光的闪灭转换成计算机识别的二进制流,而数据链路层则是把这些二进制流转换为帧,然后再进行传输。

      • 链路层的功能
        • 链路管理,帧同步
        • 流量控制,差错控制
        • 数据和控制信息分开
        • 透明传输和寻址
      • 差错控制

      当数据信号从发送端发送到物理线路时,由于物理线路存在噪声,因此数据信号经过物理线路的噪声,到达接收端时,已经是数据+噪声的叠加。这就是差错的来源。用检错码来检测帧传输过程中是否发生了差错,如果发生了错误,就需要滑动窗口协议来解决。滑动窗口协议分为两种类型:

      •     - 多帧发送协议:分为两种类型,后退N帧(GBN)拉回重发方式和选择重发(SR)方式。前者是只要有一帧发送失败,则当前发送的全部帧都重新发送,这样就会导致重发很多帧,流量控制不佳。后者是当前发送的帧中有差错,在下次发送的时候只是重新发送错误的帧就行了。  
            - 单帧停止等待协议:发送端发送1帧之后,需要等待接受端返回确认帧,如果接收到ack,表示OK,发送下一帧;如果接收到nak,表示传输错误,重新发送该帧。
        
      • 滑动窗口机制?
        在GBN和SR中,发送端可以连续发送多个数据帧,从流量控制的角度出发,发送端连续发送数据帧的数量必然会收到限制:

        • 接收端的缓冲区可以用于接受新的帧的容量
        • 接收端处理数据帧的速度
        • 接收端需要等待重传的帧的数量

      引入滑动窗口的目的:对可以连续发出的最多帧数(已发出但未确认的帧)作限制

      发送窗口(Ws):表示在收到对方确认的信息之前,以连续发出的最多数据帧数
      接受窗口(Wr):可以连续接收的最多数据帧数(只有序号在窗口内的帧才可以接收,否则丢弃)

    3. tcp中滑动窗口的原理

      • 发送窗口

      对于TCP会话的发送方,任何时候在其发送缓存内的数据都可以分为4类,“已经发送并得到对端ACK的”,“已经发送但还未收到对端ACK的”,“未发送但对端允许发送的”,“未发送且对端不允许发送”。“已经发送但还未收到对端ACK的”和“未发送但对端允许发送的”这两部分数据称之为发送窗口。当收到接收方新的ACK对于发送窗口中后续字节的确认是,窗口滑动。

      • 接受窗口

      对于TCP的接收方,在某一时刻在它的接收缓存内存在3种。“已接收”,“未接收准备接收”,“未接收并未准备接收”(由于ACK直接由TCP协议栈回复,默认无应用延迟,不存在“已接收未回复ACK”)。其中“未接收准备接收”称之为接收窗口。

      重传机制

      TCP要保证所有的数据包都可以到达,所以,必需要有重传机制。

      注意,接收端给发送端的Ack确认只会确认最后一个连续的包,比如,发送端发了1,2,3,4,5一共五份数据,接收端收到了1,2,于是回ack 3,然后收到了4(注意此时3没收到),此时的TCP会怎么办?我们要知道,因为正如前面所说的,SeqNum和Ack是以字节数为单位,所以ack的时候,不能跳着确认,只能确认最大的连续收到的包,不然,发送端就以为之前的都收到了。

      <img src="/Users/anyao/Library/Application Support/typora-user-images/image-20200403225330066.png" alt="image-20200403225330066" style="zoom:40%;" />

    4. 超时重传机制

      一种是不回ack,死等3,当发送方发现收不到3的ack超时后,会重传3。一旦接收方收到3后,会ack 回 4——意味着3和4都收到了。

      但是,这种方式会有比较严重的问题,那就是因为要死等3,所以会导致4和5即便已经收到了,而发送方也完全不知道发生了什么事,因为没有收到Ack,所以,发送方可能会悲观地认为也丢了,所以有可能也会导致4和5的重传。

      对此有两种选择:

      • 一种是仅重传timeout的包。也就是第3份数据。
      • 另一种是重传timeout后所有的数据,也就是第3,4,5这三份数据。

      这两种方式有好也有不好。第一种会节省带宽,但是慢,第二种会快一点,但是会浪费带宽,也可能会有无用功。但总体来说都不好。因为都在等timeout,timeout可能会很长(在下篇会说TCP是怎么动态地计算出timeout的)

      快速重传机制

      于是,TCP引入了一种叫Fast Retransmit 的算法,不以时间驱动,而以数据驱动重传。也就是说,如果,包没有连续到达,就ack最后那个可能被丢了的包,如果发送方连续收到3次相同的ack,就重传。Fast Retransmit的好处是不用等timeout了再重传。

      比如:如果发送方发出了1,2,3,4,5份数据,第一份先到送了,于是就ack回2,结果2因为某些原因没收到,3到达了,于是还是ack回2,后面的4和5都到了,但是还是ack回2,因为2还是没有收到,于是发送端收到了三个ack=2的确认,知道了2还没有到,于是就马上重转2。然后,接收端收到了2,此时因为3,4,5都收到了,于是ack回6。示意图如下:

      <img src="/Users/anyao/Library/Application Support/typora-user-images/image-20200403224652497.png" alt="image-20200403224652497" style="zoom:40%;" />

      Fast Retransmit只解决了一个问题,就是timeout的问题,它依然面临一个艰难的选择,就是,是重传之前的一个还是重传所有的问题。对于上面的示例来说,是重传#2呢还是重传#2,#3,#4,#5呢?因为发送端并不清楚这连续的3个ack(2)是谁传回来的?也许发送端发了20份数据,是#6,#10,#20传来的呢。这样,发送端很有可能要重传从2到20的这堆数据(这就是某些TCP的实际的实现)。可见,这是一把双刃剑。

      SACK 方法

      <img src="/Users/anyao/Library/Application Support/typora-user-images/image-20200403224744731.png" alt="image-20200403224744731" style="zoom:33%;" />

      这里还需要注意一个问题——接收方Reneging,所谓Reneging的意思就是接收方有权把已经报给发送端SACK里的数据给丢了。这样干是不被鼓励的,因为这个事会把问题复杂化了,但是,接收方这么做可能会有些极端情况,比如要把内存给别的更重要的东西。所以,发送方也不能完全依赖SACK,还是要依赖ACK,并维护Time-Out,如果后续的ACK没有增长,那么还是要把SACK的东西重传,另外,接收端这边永远不能把SACK的包标记为Ack。

    5. 拥塞机制

      如果网络上的延时突然增加,那么,TCP对这个事做出的应对只有重传数据,但是,重传会导致网络的负担更重,于是会导致更大的延迟以及更多的丢包,于是,这个情况就会进入恶性循环被不断地放大。试想一下,如果一个网络内有成千上万的TCP连接都这么行事,那么马上就会形成“网络风暴”,TCP这个协议就会拖垮整个网络。

      当拥塞发生的时候,要做自我牺牲。就像交通阻塞一样,每个车都应该把路让出来,而不要再去抢路了。拥塞

      控制主要是四个算法:

      ​ 1)慢启动,

      ​ 2)拥塞避免,

      ​ 3)拥塞发生,

      ​ 4)快速恢复。

    6. HTTPS 和 HTTP 有什么区别

      • HTTPS

        1.浏览器将自己支持的一套加密规则发送给网站。

        2.网站从中选出一组加密算法与HASH算法,并将自己的身份信息以证书的形式发回给浏览器。证书里面包含了网站地址,加密公钥,以及证书的颁发机构等信息。

        3.获得网站证书之后浏览器要做以下工作:

        a) 验证证书的合法性(颁发证书的机构是否合法,证书中包含的网站地址是否与正在访问的地址一致等),如果证书受信任,则浏览器栏里面会显示一个小锁头,否则会给出证书不受信的提示。

        b) 如果证书受信任,或者是用户接受了不受信的证书,浏览器会生成一串随机数的密码,并用证书中提供的公钥加密。

        c) 使用约定好的HASH计算握手消息,并使用生成的随机数对消息进行加密,最后将之前生成的所有信息发送给网站。

        4.网站接收浏览器发来的数据之后要做以下的操作:

        a) 使用自己的私钥将信息解密取出密码,使用密码解密浏览器发来的握手消息,并验证HASH是否与浏览器发来的一致。

        b) 使用密码加密一段握手消息,发送给浏览器。

        5.浏览器解密并计算握手消息的HASH,如果与服务端发来的HASH一致,此时握手过程结束,之后所有的通信数据将由之前浏览器生成的随机密码并利用对称加密算法进行加密。

        <img src="https://cdn.jsdelivr.net/gh/0vo/res/images/https.jpg" alt="img" style="zoom:25%;" />

      • HTTPS 和 HTTP 有什么区别

        • HTTP 明文传输,数据都是未加密的,安全性较差,HTTPS(SSL+HTTP) 数据传输过程是加密的,安全性较好。
        • 使用 HTTPS 协议需要到 CA(Certificate Authority,数字证书认证机构) 申请证书,一般免费证书较少,因而需要一定费用。证书颁发机构如:Symantec、Comodo、GoDaddy 和 GlobalSign 等。
        • HTTP 页面响应速度比 HTTPS 快,主要是因为 HTTP 使用 TCP 三次握手建立连接,客户端和服务器需要交换 3 个包,而 HTTPS除了 TCP 的三个包,还要加上 ssl 握手需要的 9 个包,所以一共是 12 个包。
        • http 和 https 使用的是完全不同的连接方式,用的端口也不一样,前者是 80,后者是 443。
        • HTTPS 其实就是建构在 SSL/TLS 之上的 HTTP 协议,所以,要比较 HTTPS 比 HTTP 要更耗费服务器资源。
    7. 100Mbps的带宽三个人使用,每人50Mbps,tcp怎么保证速度的

      多TCP连接,可以充分利用带宽,用状态表示每个TCP的连接状况,可以共享TCP连接。

      单个TCP: 滑动窗口、快速重传、延迟应答、捎带应答

    8. 一个完整的 HTTP 请求会涉及到哪些协议?

      <img src="https://user-gold-cdn.xitu.io/2017/11/11/690219fae5b0587fa26e2dee545e6200?imageslim" alt="img" style="zoom:60%;" />

    9. 长连接和短链接区别,应用场景。

      在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协议的长连接和短连接。

      长连接多用于操作频繁,点对点的通讯,而且连接数不能太多情况,。每个TCP连接都需要三步握手,这需要时间,如果每个操作都是先连接,再操作的话那么处理速度会降低很多,所以每个操作完后都不断开,次处理时直接发送数据包就OK了,不用建立TCP连接。例如:数据库的连接用长连接, 如果用短连接频繁的通信会造成socket错误,而且频繁的socket 创建也是对资源的浪费。

      而像WEB网站的http服务一般都用短链接,因为长连接对于服务端来说会耗费一定的资源,而像WEB网站这么频繁的成千上万甚至上亿客户端的连接用短连接会更省一些资源,如果用长连接,而且同时有成千上万的用户,如果每个用户都占用一个连接的话,那可想而知吧。所以并发量大,但每个用户无需频繁操作情况下需用短连好。

    10. Ping用的协议

      ICMP:Internet控制报文协议。由于IP协议并不是一个可靠的协议,它不保证数据被成功送达,那么,如何才能保证数据的可靠送达呢? 这里就需要使用到一个重要的协议模块ICMP(网络控制报文)协议。它传递差错报文以及其他需要注意的信息,经常供IP层或更高层协议(TCP或UDP)使用。所以它经常被认为是IP层的一个组成部分。

    11. TCP半连接客户端怎么接消息

      tcp连接一端在进行完三次握手以后进入ESTABLISHED状态,如果连接的对端在某一时刻在网络中消失,而本端没有感知到,还是处于ESTABLISHED状态,那么本端的连接就被称为半打开连接(Half Open)。

    12. 你了解DDoS攻击吗?

      那 DDoS 攻击究竟是什么?可能我举个例子会更加形象点。我开了一家有五十个座位的重庆火锅店,由于用料上等,童叟无欺。平时门庭若市,生意特别红火,而对面二狗家的火锅店却无人问津。二狗为了对付我,想了一个办法,叫了五十个人来我的火锅店坐着却不点菜,让别的客人无法吃饭。

      上面这个例子讲的就是典型的 DDoS 攻击,全称是 Distributed Denial of Service,翻译成中文就是分布式拒绝服务。一般来说是指攻击者利用“肉鸡”对目标网站在较短的时间内发起大量请求,大规模消耗目标网站的主机资源,让它无法正常服务。在线游戏、互联网金融等领域是 DDoS 攻击的高发行业。

      • 如何应对 DDoS攻击?
        • 高防服务器
          还是拿我开的重庆火锅店举例,高防服务器就是我给重庆火锅店增加了两名保安,这两名保安可以让保护店铺不受流氓骚扰,并且还会定期在店铺周围巡逻防止流氓骚扰。高防服务器主要是指能独立硬防御 50Gbps 以上的服务器,能够帮助网站拒绝服务攻击,定期扫描网络主节点等,这东西是不错,就是贵~
        • 黑名单
          面对火锅店里面的流氓,我一怒之下将他们拍照入档,并禁止他们踏入店铺,但是有的时候遇到长得像的人也会禁止他进入店铺。这个就是设置黑名单,此方法秉承的就是“错杀一千,也不放一百”的原则,会封锁正常流量,影响到正常业务。
        • DDoS 清洗
          DDos 清洗,就是我发现客人进店几分钟以后,但是一直不点餐,我就把他踢出店里。DDoS 清洗会对用户请求数据进行实时监控,及时发现DOS攻击等异常流量,在不影响正常业务开展的情况下清洗掉这些异常流量。
        • CDN 加速
          CDN 加速,我们可以这么理解:为了减少流氓骚扰,我干脆将火锅店开到了线上,承接外卖服务,这样流氓找不到店在哪里,也耍不来流氓了。在现实中,CDN 服务将网站访问流量分配到了各个节点中,这样一方面隐藏网站的真实 IP,另一方面即使遭遇 DDoS 攻击,也可以将流量分散到各个节点中,防止源站崩溃。
    13. xss跨域是什么

      它指的是恶意攻击者往Web页面里插入恶意html代码,当用户浏览该页之时,嵌入其中Web里面的html代码会被执行,从而达到恶意用户的特殊目的。

      它与SQL注入攻击类似,SQL注入攻击中以SQL语句作为用户输入,从而达到查询/修改/删除数据的目的,而在xss攻击中,通过插入恶意脚本,实现对用户游览器的控制,获取用户的一些信息。

    14. RPC相对于传统的API调用的优点

      [图片上传失败...(image-993303-1586424088414)]

    15. request数据是如何流转的

    • http请求是如何建立起来

      <img src="http://images.haohongfan.com/socket.png?imageView2/0/w/700/h/700/q/75" alt="socket" style="zoom:100%;" />

      注册路由:注册一个路由及这个路由的handler到DefaultServeMux中。

      服务监听及响应

      • ln, err := net.Listen("tcp", addr)做了初试化了socket, bind, listen的操作.
      • rw, e := l.Accept()进行accept, 等待客户端进行连接
      • go c.serve(ctx) 启动新的goroutine来处理本次请求. 同时主goroutine继续等待客户端连接, 进行高并发操作
      • h, _ := mux.Handler(r) 获取注册的路由, 然后拿到这个路由的handler, 然后将处理结果返回给客户端

    相关文章

      网友评论

          本文标题:网络协议

          本文链接:https://www.haomeiwen.com/subject/lcthmhtx.html