# OSI 七层网络模型
OSI 的七层协议主要包括:物理层(physical layer)、数据链路层(data link layer)、网络层(network layer)、运输层(transport layer)、会话层(session layer)、表示层(presentation layer)、应用层(application layer)。
OSI 七层网络模型 | 功能 | 常用网络协议 |
---|---|---|
应用层 | 应用层是网络体系中最高的一层,也是唯一面向用户的一层,也可视为为用户提供常用的应用程序,每个网络应用都对应着不同的协议 | HTTP、TFTP, FTP, NFS, WAIS、SMTP |
表示层 | 主要负责数据格式的转换,确保一个系统的应用层发送的消息可以被另一个系统的应用层读取,编码转换,数据解析,管理数据的解密和加密,同时也对应用层的协议进行翻译 | JPEG、MPEG、ASII |
会话层 | 负责网络中两节点的建立,在数据传输中维护计算机网络中两台计算机之间的通信连接,并决定何时终止通信 | SMTP, DNS |
传输层 | 是整个网络关键的部分,是实现两个用户进程间端到端的可靠通信,处理数据包的错误等传输问题。是向下通信服务最高层,向上用户功能最底层。即向网络层提供服务,向会话层提供独立于网络层的传送服务和可靠的透明数据传输 | TCP, UDP |
网络层 | 将传输层传下来的报文段封装成分组,选择合适的路由,使得传输层传下来的分组能够交付到目的主机 | IP、ICMP、ARP、RARP、OSPF、IPX、RIP、IGRP(交换机) |
数据链路层 | 物理地址(MAC 地址),网络设备的唯一身份标识。建立逻辑连接、进行硬件地址寻址,相邻的两个设备间的互相通信 | PPP、FR、HDLC、VLAN、MAC(网桥、交换机) |
物理层 | 七层模型中的最底层,主要是物理介质传输媒介(网线或者是无线),在不同设备中传输比特,将 0/1 信号与电信号或者光信号互相转化 | IEEE 802.1A, IEEE 802.2 到 IEEE 802 (中继器、集线器) |
# 三次握手 & 四次挥手
# 三次握手
# 三次握手示意图
- 客户端在需要时,向服务器发起请求连接报文,发出后状态从 CLOSED 转换为 SYN-SEND 同步 - 已发送状态。
- 服务器一直处于 LISTEN 状态,接收到请求后,对客户端的请求进行回应,转换为 SYN-RCVD,同步 - 已收到状态。
- 客户端收到服务器的回应后,状态转换为 ESTABLISHED,并且再次向服务器发送确认。
- 服务器收到客户端的确认之后,服务器也转换为 ESTABLISHED 状态,完成了连接。
# 三次握手过程
- 客户端发送一个 SYN0 给服务器(选择初始序列号,不携带任何数据)
- 服务器收到 SYN0,回复 SYN1 和 ACK(服务器分配缓存,选择自己初始序列号)
- 客户端收到 SYN1、ACK,回复 ACK(可以包含数据)
# 为什么要三次握手
如果不是三次握手,只有两次
如果客户端发出请求连接时,报文延时了,于是客户端重新发送了一次连接请求消息
后来收到了确认,建立了连接,然后完成了数据传输,关闭了连接
此时,服务器收到了那个迟到的请求消息,此时这个请求不应该建立双向的连接。
但是如果只有两次握手,服务器收到请求就响应建立了连接了
但是如果是三次,客户端不会再次确认,服务器也就随后知道了这消息有问题,不会建立连接
# 四次挥手
# 四次挥手示意图
-
客户端进程发出连接释放报文,并且停止发送数据。释放数据报文首部,FIN=1,其序列号为 seq=u(等于前面已经传送过来的数据的最后一个字节的序号加 1),此时,客户端进入 FIN-WAIT-1(终止等待 1)状态。 TCP 规定,FIN 报文段即使不携带数据,也要消耗一个序号。
-
服务器收到连接释放报文,发出确认报文,ACK=1,ack=u+1,并且带上自己的序列号 seq=v,此时,服务端就进入了 CLOSE-WAIT(关闭等待)状态。TCP 服务器通知高层的应用进程,客户端向服务器的方向就释放了,这时候处于半关闭状态,即客户端已经没有数据要发送了,但是服务器若发送数据,客户端依然要接受。这个状态还要持续一段时间,也就是整个 CLOSE-WAIT 状态持续的时间。
-
客户端收到服务器的确认请求后,此时,客户端就进入 FIN-WAIT-2(终止等待 2)状态,等待服务器发送连接释放报文(在这之前还需要接受服务器发送的最后的数据)。
-
服务器将最后的数据发送完毕后,就向客户端发送连接释放报文,FIN=1,ack=u+1,由于在半关闭状态,服务器很可能又发送了一些数据,假定此时的序列号为 seq=w,此时,服务器就进入了 LAST-ACK(最后确认)状态,等待客户端的确认。
-
客户端收到服务器的连接释放报文后,必须发出确认,ACK=1,ack=w+1,而自己的序列号是 seq=u+1,此时,客户端就进入了 TIME-WAIT(时间等待)状态。注意此时 TCP 连接还没有释放,必须经过 2∗∗MSL(最长报文段寿命)的时间后,当客户端撤销相应的 TCB 后,才进入 CLOSED 状态。
-
服务器只要收到了客户端发出的确认,立即进入 CLOSED 状态。同样,撤销 TCB 后,就结束了这次的 TCP 连接。可以看到,服务器结束 TCP 连接的时间要比客户端早一些。
# 四次挥手过程:
- 客户端向服务器发送 FIN 控制报文段(首部中的 FIN 比特被置位);
- 服务端收到 FIN,回复 ACK。服务器进入关闭等待状态,发送 FIN;
- 客户端收到 FIN,给服务器回复 ACK,客户端进入等待状态(进入 “等待”,以确保服务器收到 ACK 真正关闭连接);
- 服务端收到 ACK,链接关闭。
# 四次挥手原因:
TCP 协议是一种面向连接的、可靠的、基于字节流的运输层通信协议。TCP 是全双工模式,这就意味着,当客户端发出 FIN 报文段时,只是表示客户端已经没有数据要发送了,客户端告诉服务器,它的数据已经全部发送完毕了;但是,这个时候客户端还是可以接受来自服务端的数据;当服务端返回 ACK 报文段时,表示它已经知道客户端没有数据发送了,但是服务端还是可以发送数据到客户端的;当服务端也发送了 FIN 报文段时,这个时候就表示服务端也没有数据要发送了,就会告诉客户端,我也没有数据要发送了,之后彼此就会愉快的中断这次 TCP 连接。
# 粘包
TCP 粘包就是指发送方发送的若干包数据到达接收方时粘成了一包,从接收缓冲区来看,后一包数据的头紧接着前一包数据的尾,出现粘包的原因是多方面的,可能是来自发送方,也可能是来自接收方。
# 原因
- 发送方原因
TCP 默认使用 Nagle 算法(主要作用:减少网络中报文段的数量),而 Nagle 算法主要做两件事:
- 只有上一个分组得到确认,才会发送下一个分组
- 收集多个小分组,在一个确认到来时一起发送
- 接收方原因
TCP 接收到数据包时,并不会马上交到应用层进行处理,或者说应用层并不会立即处理。实际上,TCP 将接收到的数据包保存在接收缓存里,然后应用程序主动从缓存读取收到的分组。这样一来,如果 TCP 接收数据包到缓存的速度大于应用程序从缓存中读取数据包的速度,多个包就会被缓存,应用程序就有可能读取到多个首尾相接粘到一起的包。
# 处理方式
- 发送端将每个包都封装成固定的长度,比如 100 字节大小。如果不足 100 字节可通过补 0 或空等进行填充到指定长度;
- 发送端在每个包的末尾使用固定的分隔符,例如
\r\n
。如果发生拆包需等待多个包发送过来之后再找到其中的、r\n 进行合并;例如,FTP 协议; - 将消息分为头部和消息体,头部中保存整个消息的长度,只有读取到足够长度的消息之后才算是读到了一个完整的消息;
# 为什么 UDP 没有粘包
粘包拆包问题在数据链路层、网络层以及传输层都有可能发生。日常的网络应用开发大都在传输层进行,由于 UDP 有消息保护边界,不会发生粘包拆包问题,因此粘包拆包问题只发生在 TCP 协议中。
# HTTP & HTTPS
# HTTP
HTTP 协议是 Hyper Text Transfer Protocol(超文本传输协议)的缩写,是用于从万维网(WWW:World Wide Web )服务器传输超文本到本地浏览器的传送协议。
# HTTP 请求方法
HTTP1.0 定义了三种请求方法: GET, POST 和 HEAD 方法。
HTTP1.1 新增了六种请求方法:OPTIONS、PUT、PATCH、DELETE、TRACE 和 CONNECT 方法。
REQUEST METHOD | 描述 |
---|---|
GET | 请求指定的页面信息,并返回实体主体。 |
HEAD | 类似于 GET 请求,只不过返回的响应中没有具体的内容,用于获取报头。 |
POST | 向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。数据被包含在请求体中。POST 请求可能会导致新的资源的建立和 / 或已有资源的修改。 |
PUT | 从客户端向服务器传送的数据取代指定的文档的内容。 |
DELETE | 请求服务器删除指定的页面。 |
CONNECT | HTTP/1.1 协议中预留给能够将连接改为管道方式的代理服务器。 |
OPTIONS | 允许客户端查看服务器的性能。 |
TRACE | 回显服务器收到的请求,主要用于测试或诊断。 |
PATCH | 是对 PUT 方法的补充,用来对已知资源进行局部更新 。 |
# HTTP 状态码
状态码 | 状态码英文名称 | 中文描述 | |
---|---|---|---|
100 | Continue | 继续。客户端应继续其请求 | |
101 | Switching Protocols | 切换协议。服务器根据客户端的请求切换协议。只能切换到更高级的协议,例如,切换到 HTTP 的新版本协议 | |
200 | OK | 请求成功。一般用于 GET 与 POST 请求 | |
201 | Created | 已创建。成功请求并创建了新的资源 | |
202 | Accepted | 已接受。已经接受请求,但未处理完成 | |
203 | Non-Authoritative Information | 非授权信息。请求成功。但返回的 meta 信息不在原始的服务器,而是一个副本 | |
204 | No Content | 无内容。服务器成功处理,但未返回内容。在未更新网页的情况下,可确保浏览器继续显示当前文档 | |
205 | Reset Content | 重置内容。服务器处理成功,用户终端(例如:浏览器)应重置文档视图。可通过此返回码清除浏览器的表单域 | |
206 | Partial Content | 部分内容。服务器成功处理了部分 GET 请求 | |
300 | Multiple Choices | 多种选择。请求的资源可包括多个位置,相应可返回一个资源特征与地址的列表用于用户终端(例如:浏览器)选择 | |
301 | Moved Permanently | 永久移动。请求的资源已被永久的移动到新 URI,返回信息会包括新的 URI,浏览器会自动定向到新 URI。今后任何新的请求都应使用新 | 的 URI 代替 |
302 | Found | 临时移动。与 301 类似。但资源只是临时被移动。客户端应继续使用原有 URI | |
303 | See Other | 查看其它地址。与 301 类似。使用 GET 和 POST 请求查看 | |
304 | Not Modified | 未修改。所请求的资源未修改,服务器返回此状态码时,不会返回任何资源。客户端通常会缓存访问过的资源,通过提供一个头信息指出客户端希望只返回在指定日期之后修改的资源 | |
305 | Use Proxy | 使用代理。所请求的资源必须通过代理访问 | |
306 | Unused | 已经被废弃的 HTTP 状态码 | |
307 | Temporary Redirect | 临时重定向。与 302 类似。使用 GET 请求重定向 | |
400 | Bad Request | 客户端请求的语法错误,服务器无法理解 | |
401 | Unauthorized | 请求要求用户的身份认证 | |
402 | Payment Required | 保留,将来使用 | |
403 | Forbidden | 服务器理解请求客户端的请求,但是拒绝执行此请求 | |
404 | Not Found | 服务器无法根据客户端的请求找到资源(网页)。通过此代码,网站设计人员可设置 "您所请求的资源无法找到" 的个性页面 | |
405 | Method Not Allowed | 客户端请求中的方法被禁止 | |
406 | Not Acceptable | 服务器无法根据客户端请求的内容特性完成请求 | |
407 | Proxy Authentication Required | 请求要求代理的身份认证,与 401 类似,但请求者应当使用代理进行授权 | |
408 | Request Time-out | 服务器等待客户端发送的请求时间过长,超时 | |
409 | Conflict 服务器完成客户端的 PUT | 请求时可能返回此代码,服务器处理请求时发生了冲突 | |
410 | Gone | 客户端请求的资源已经不存在。410 不同于 404,如果资源以前有现在被永久删除了可使用 410 代码,网站设计人员可通过 301 代码指定资源的新位置 | |
411 | Length Required | 服务器无法处理客户端发送的不带 Content-Length 的请求信息 | |
412 | Precondition Failed | 客户端请求信息的先决条件错误 | |
413 | Request Entity Too Large | 由于请求的实体过大,服务器无法处理,因此拒绝请求。为防止客户端的连续请求,服务器可能会关闭连接。如果只是服务器暂时无法处理,则会包含一个 Retry-After 的响应信息 | |
414 | Request-URI Too Large | 请求的 URI 过长(URI 通常为网址),服务器无法处理 | |
415 | Unsupported Media Type | 服务器无法处理请求附带的媒体格式 | |
416 | Requested range not satisfiable | 客户端请求的范围无效 | |
417 | Expectation Failed | 服务器无法满足 Expect 的请求头信息 | |
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 协议的版本,无法完成处理 |
# RESTFULL
GET /collection:从服务器查询资源的列表(数组) | |
GET /collection/resource:从服务器查询单个资源 | |
POST /collection:在服务器创建新的资源 | |
PUT /collection/resource:更新服务器资源 | |
DELETE /collection/resource:从服务器删除资源 |
四个方法除 POST 之外都需要保持幂等性。
# HTTPS
HTTPS(Hyper Text Transfer Protocol over SecureSocket Layer)是以安全为目标的 HTTP 通道,是 HTTP 的安全版。HTTPS 的安全基础是 SSL。SSL 协议位于 TCP/IP 协议与各种应用层协议之间,为数据通讯提供安全支持。SSL 协议可分为两层:SSL 记录协议(SSL Record Protocol),它建立在可靠的传输协议(如 TCP)之上,为高层协议提供数据封装、压缩、加密等基本功能的支持。SSL 握手协议(SSL Handshake Protocol),它建立在 SSL 记录协议之上,用于在实际的数据传输开始前,通讯双方进行身份认证、协商加密算法、交换加密密钥等。
客户端在使用 HTTPS 方式与 Web 服务器通信时有以下几个步骤,如图上图所示:
- 客户使用 https 的 URL 访问 Web 服务器,要求与 Web 服务器建立 SSL 连接。
- Web 服务器收到客户端请求后,会将网站的证书信息(证书中包含公钥)传送一份给客户端。
- 客户端的浏览器与 Web 服务器开始协商 SSL 连接的安全等级,也就是信息加密的等级。
- 客户端的浏览器根据双方同意的安全等级,建立会话密钥,然后利用网站的公钥将会话密钥加密,并传送给网站。
- Web 服务器利用自己的私钥解密出会话密钥。
- Web 服务器利用会话密钥加密与客户端之间的通信。
# 其它问题
-
介绍一下 HTTP 协议中的长连接和短连接。
HTTP 协议的底层使用 TCP 协议,所以 HTTP 协议的长连接和短连接在本质上是 TCP 层的长连接和短连接。由于 TCP 建立连接、维护连接、释放连接都是要消耗一定的资源,浪费一定的时间。所对于服务器来说,频繁的请求释放连接会浪费大量的时间,长时间维护太多的连接的话又需要消耗资源。所以长连接和短连接并不存在优劣之分,只是适用的场合不同而已。长连接和短连接分别有如下优点和缺点:
长连接优点:可以节省较多的 TCP 连接和释放的操作,节约时间,对于频繁请求资源的用户来说,适合长连接。
长连接缺点:由于有保活功能,当遇到大量的恶意连接时,服务器的压力会越来越大。这时服务器需要采取一些策略,关闭一些长时间没有进行读写事件的的连接。
短连接优点:短连接对服务器来说管理比较简单,只要存在的连接都是有效连接,不需要额外的控制手段,而且不会长时间占用资源 。
短连接缺点:如果客户端请求频繁的话,会在 TCP 的建立和释放上浪费大量的时间。
从 HTTP/1.1 版本起,默认使用长连接用以保持连接特性。使用长连接的 HTTP 协议,会在响应消息报文段加入:Connection: keep-alive。TCP 中也有 keep alive,但是 TCP 中的 keep alive 只是探测 TCP 连接是否活着,而 HTTP 中的 keep-alive 是让一个 TCP 连接获得更久一点。 -
说一说 HTTPS 的证书认证过程。
-
浏览器将自己支持的一套加密规则发送给网站。
-
网站从中选出一组加密算法与 HASH 算法,并将自己的身份信息以证书的形式发回给浏览器。证书里面包含了网站地址,加密公钥,以及证书的颁发机构等信息。
-
浏览器获得网站证书之后浏览器要做以下工作:
- 验证证书的合法性(颁发证书的机构是否合法,证书中包含的网站地址是否与正在访问的地址一致等),如果证书受信任,则浏览器栏里面会显示一个小锁头,否则会给出证书不受信的提示。
- 如果证书受信任,或者是用户接受了不受信的证书,浏览器会生成一串随机数的密码,并用证书中提供的公钥加密。
- 使用约定好的 HASH 算法计算握手消息,并使用生成的随机数对消息进行加密,最后将之前生成的所有信息发送给网站。
- 网站接收浏览器发来的数据之后要做以下的操作:
- 使用自己的私钥将信息解密取出密码,使用密码解密浏览器发来的握手消息,并验证 HASH 是否与浏览器发来的一致。
- 使用密码加密一段握手消息,发送给浏览器。
- 浏览器解密并计算握手消息的 HASH,如果与服务端发来的 HASH 一致,此时握手过程结束,之后所有的通信数据将由之前浏览器生成的随机密码并利用对称加密算法进行加密。
-
-
打开浏览器从输入网址到网页呈现在大家面前,背后发生了什么?
DNS 解析:将域名解析成 IP 地址
TCP 连接:TCP 三次握手
发送 HTTP 请求
服务器处理请求并返回 HTTP 报文
浏览器解析渲染页面
断开连接:TCP 四次挥手