1. 简述TCP/IP网络模型
对于不同设备上进程之间的通信需求,需要通过网络通信完成。为了兼容多种多样的设备能够以同样的形式交换数据(包括发送和接收),人们建立起了许多规则,这些规则、标准或是约定的集合称为协议。用于网络通信的协议就称为网络协议或通信协议。
TCP/IP模型就是由一组网络协议构成的体系结构,通常划分为五层。类似的体系结构还有OSI七层网络模型。
2. 模型中每层内容
以OSI七层模型为例来更细致地展开,对应到TCP/IP协议每层通用。由下至上地阐述。
物理层(Physical Layer)
负责激活、维持及关闭通信端点之间的机械特性、电气特性和过程特性。该层为上层协议提供了一个传输数据的可靠的物理媒介。简单地说,物理层确保原始的数据可在各种物理媒介上传输。
- 基本数据单位为比特(bit);
- 重要设备名称:中继器(Repeater,也叫放大器)。
数据链路层(Data Link Layer)
- 数据链路层为数据提供可靠的数据传输;
- 基本数据单位为帧(frame);
- 主要的协议:
以太网协议; - 重要设备名称:网桥和交换机。
网络层(Network Layer)
实现两个通信端点之间数据的透明传输。具体的功能包括寻址;路由选择;连接的建立、保持和终止等。
该层包含TCP/IP核心之一的IP协议。IP协议非常简单,仅仅提供不可靠、无连接的数据传输服务。主要功能有:无连接数据报传输、数据报路由选择和差错控制。
- 网络层负责对子网之间的数据进行路由选择;
- 基本数据单位为数据包(packet);
- 主要的协议:
IP(因特网互联协议)ICMP(因特网控制报文协议)ARP(地址解析协议)RARP(逆地址解析协议)
- 重要设备名称:路由器。
传输层(Transport Layer)
这是第一个端到端,即主机到主机的层次。传输层负责将上层数据分段并提供端到端的、可靠(TCP)或不可靠(UDP)的传输。此外,传输层还要处理端到端的差错控制和流量控制问题。网络层只是根据网络地址将源节点发出的数据包传送到目的节点,而传输层则负责将数据可靠地传送至相应的端口。
- 传输层负责将上层数据分段,并根据通信子网的特性,最佳地利用网络资源,为两个端系统的会话层之间提供建立、维护和取消传输连接的功能,负责端到端的可靠或不可靠数据传输以及端到端的差错控制和流量控制问题;
- 基本数据单位为数据段(segment);
- 主要的协议:
TCP(传输控制协议)UDP(用户数据报协议)
- 重要设备名称:网关。
会话层(Session Layer)
管理主机之间的会话进程,即负责建立、管理和终止进程之间的会话。会话层还利用在数据中插入校验点的方法来实现数据的同步。
表示层(Presentation Layer)
表示层对上层数据或信息进行变换以保证一个主机应用层信息可以被另一个主机的应用程序理解。表示层的数据转换包括数据的加密、压缩和格式转换等。
应用层(Application Layer)
- 为操作系统或网络应用程序提供访问网络服务的接口;
- 基本数据单位为报文;
- 主要的协议:
FTP(文件传送协议)Telnet(远程登录协议)DNS(域名解析协议)SMTP(邮件传送协议)POP3(邮局协议)HTTP(Hyper Text Transfer Protocol)
3. 输入网址到网页显示的期间发生了什么
- 通过
HTTP协议解析 URL,对 URL 进行解析之后,浏览器确定了 Web 服务器和文件名,接下来就是根据这些信息来生成 HTTP 请求消息了。 - 通过
DNS协议查询到服务器域名对应的IP地址,因为委托操作系统发送消息时,必须提供通信对象的IP地址。 - 通过 DNS 获取到 IP 后,就可以把 HTTP 的传输工作交给操作系统中的
协议栈。 - 通过
TCP协议建立可靠的连接(三次握手),并将 HTTP 报文加上 TCP 头,组装为 TCP 报文。 - 通过
IP协议确定源地址IP和目标地址IP,将 TCP 报文加上 IP 头组装为 IP 报文。 - 将接收方 MAC 地址和发送方 MAC 地址以及协议类型作为 MAC 头加在 IP 报文前组成 MAC 报文。 MAC 头的作用就是将数据包送达路由器。
- 网卡将数据包的数据信息转换为电信号,通过网线发送出去。
- 经过交换机,到达路由器。路由器会去掉数据包的 MAC 头,并根据 IP 头中的内容进行包的转发操作。
- 数据包抵达服务器后,服务器会先检查数据包的 MAC 头,和服务器自己的 MAC 地址符合就将包收起来,然后检查 IP 头,发现 IP 地址符合,并根据 IP 头中协议项得知上层使用 TCP 协议,然后检查 TCP 头,根据序列号看这个包是不是当前需要的。 TCP 头中还有端口号, HTTP 的进程正在监听这个端口号,服务器就知道是 HTTP 进程想要这个包,于是就将包发给 HTTP 进程。
- 服务器里的 HTTP 进程根据包中的数据看到这是要请求一个网页页面,于是就将这个网页封装在 HTTP 响应报文里。
- 然后再经过和之前一样的流程,加上各种协议头传回给客户端,客户端接收到 HTTP 响应报文后,交给浏览器去渲染页面,页面就展现到了用户面前。
- 客户端向服务器发起四次挥手,断开双方连接。
4. TCP协议三次握手过程
第一次握手
客户端将标志位 SYN 置为1,随机产生一个值x,使序列号 seq = x,并将该数据包发送给服务端,客户端进入syn_sent状态,等待服务端确认。
第二次握手
服务端收到数据包后由标志位 SYN = 1 知道客户端请求建立连接,服务端将标志位 SYN 和 ACK 都置为1,使 ack = x + 1,随机产生一个值y,使序列号 seq = y,并将该数据包发送给客户端以确认连接请求,服务端进入syn_rcvd状态。
第三次握手
客户端收到确认后检查,如果正确则将标志位 ACK 置为1,使 ack = y + 1,并将该数据包发送给服务端,服务端进行检查如果正确则连接建立成功,客户端和服务端进入established状态,完成三次握手,随后客户端和服务端之间可以开始传输数据了。
5. HTTP 是什么?
HyperText Transfer Protocal, 超文本传输协议。
- 超文本:互联网在早期时只是简单的字符文字,这些字符称为“文本”,随着互联网的发展,如今广义的“文本”含义可以涵盖图片、视频和压缩包等类型文件,这些文件在 HTTP 世界里都属于“文本”。至于“超文本”,即意为超越了普通文本的文本,是包括但不限于字符、图片及视频等的混合体,关键在于有超链接,能够从一个超文本跳转至另一个超文本。
- 传输:互联网的“传输”,即将数据从一个点发送至另一个点。HTTP是双向协议,即基于 HTTP 协议来通信的数据可以从A传输至B,也可以由B传输至A。且允许有中转或接力,即数据从出发点发出后,可以经过别的点之后再到目的点。
- 协议:如前文所述。
规则、标准或是约定的集合称为协议
可以总结出:HTTP 是一个在计算机世界里专门在两点之间传输文字、图片及视频等超文本数据的约定和规则。
6. HTTP 常见状态码有哪些?分别是什么意思?
1xx类状态码属于提示信息,表示目前是协议处理的中间状态,还需要后续的操作。实际中使用到的比较少。
2xx类状态码表示服务器成功处理了客户端的请求。
- 「200 OK」是最常见的成功状态码,表示一切正常。如果是非 HEAD 请求,服务器返回的响应头都会有 body 数据。
- 「204 No Content」和200类似,都是常见的成功状态码,但响应头没有 body 数据。
- 「206 Partial Content」也是处理成功的状态,用于 HTTP 分块下载或断点续传,表示响应返回的 body 数据并不是资源的全部,而是其中一部分。
3xx类状态码表示客户端请求的资源发生了变动,需要重定向,即需要客户端用新的URL重新发送请求以获得资源。
- 「301 Moved Permanently」表示永久重定向,原本请求的资源已经不存在了,需要用新的URL再次访问。
- 「302 Found」临时重定向,请求的资源还在,但暂时需要用新的URL访问。
301和302状态都会在响应头里使用字段Location,指明后续要跳转的URL,浏览器会自动重定向到新的URL。
4xx类状态码表示客户端发送的报文有误,服务器无法处理请求。是客户端的错误码。
- 「400 Bad Request」表示客户端请求的报文有错误,但是这个错误很笼统,是什么错误也不知道。
- 「403 Forbidden」表示服务器禁止该客户端访问该资源,并不是客户端请求出错。
- 「404 Not Found」表示客户端请求的资源在服务器上不存在或找不到,所以无法返回给客户端。
5xx类状态码表示客户端请求报文正确,但服务器处理时内部发生了错误。是服务器的错误码。
- 「500 Internal Server Error」与400类似,是笼统的错误码,只不过这个是服务器出错。
- 「501 Not Implemented」表示客户端请求的功能目前服务器还不支持。
- 「502 Bad Gateway」通常是服务器作为网关或者代理时返回的错误码,表示服务器自身工作正常,但是访问后端资源时发生错误。
- 「503 Service Unavailable」表示服务器当前忙,暂时无法响应客户端。
7. GET和POST的区别?
根据 RFC 规范:
- GET 的语义是从服务器获取指定的资源。
- POST 的语义是根据请求负荷(报文body)对指定的资源做出处理(创建或提交)。
从【安全】、【幂等】和【缓存】三方面看GET和POST的区别:
安全:在 HTTP 协议里,“安全”指请求方法不会“破坏”服务器上的资源。
幂等:指多次执行相同的操作,得到的结果是相同的。
- GET 方法是“只读”操作,无论操作多少次,服务器上的资源都是安全的,且每次请求获得的结果都是相同的。所以 GET 方法是安全且幂等的,可以对 GET 请求的数据做缓存,这个缓存可以做在浏览器本身上(就能彻底避免浏览器发请求),也可以做到代理上(如nginx),浏览器中 GET 请求也可以保存为书签。
- POST 方法是“创建或提交”数据的操作,会修改服务器上的资源,所以是不安全的。多次提交数据就会创建多个资源,所以也是不幂等的。故浏览器一般也不会缓存 POST 请求,也不能把 POST 请求保存为书签。
| 安全 | 幂等 | 缓存 | |
|---|---|---|---|
| GET | ✅ | ✅ | ✅ |
| POST | ❌ | ❌ | ❌ |
以上分析都建立在遵循 RFC 规范的情况下,现实使用中有许多人并没有完全遵循规范。
8. 什么是 HTTP 缓存,有哪些实现方式?
一些具有重复性的 HTTP 请求,例如每次请求得到的数据都一样的,可以把这对“请求-响应”的数据都缓存在本地,以后再有这个请求就可以直接读取本地的数据,以实现性能的提升。
HTTP 有两种实现方式:
- 强制缓存
- 协商缓存
什么是强制缓存?
强制缓存是只要浏览器判断缓存没有过期,则直接使用浏览器的本地缓存,由浏览器主动决定是否使用缓存。
强制缓存利用 HTTP 响应头(Response Header)中的两个表示资源在客户端缓存的有效期的字段实现:
Cache-Control,相对时间
- 当浏览器第一次请求访问服务器资源时,服务器会在返回这个资源的同时,在响应头加上 Cache-Control,这里面设置了过期时间大小;
- 浏览器再次请求访问服务器中的该资源时,会先通过请求资源的时间与 Cache-Control 中设置的过期时间大小来计算该资源的本地缓存是否过期,如未过期则直接使用缓存,如过期则重新请求服务器;
- 服务器再次收到请求的话会再更新响应头里的Cache-Control。
Expires,绝对时间
如果 HTTP 响应头同时有 Cache-Control 和 Expires 字段的话, Cache-Control 的优先级高于 Expires。
什么是协商缓存?
在浏览器使用开发者工具时,可能会在某些请求的响应码中看到 304 ,这是服务器返回给客户端告诉浏览器可以使用本地缓存的资源。这个响应码是服务器在对比请求资源和现有资源一致后返回的让客户端哪怕过期也可以继续使用本地缓存的协商结果,所以协商缓存就是客户端与服务端协商后,根据协商结果判断是否使用本地缓存。
协商缓存可以基于两种头部标识来实现:
- 通过响应头中的
Last-Modified字段和请求头中的If-Modified-Since字段实现,这两个字段的意思是:
- 响应头中的
Last-Modified表示该响应资源的最后修改时间 - 请求头中的
If-Modified-Since,顾名思义“如在xx时间后有修改”。是当本地资源过期后,客户端发现响应头中有 Last-Modified 声明,则再次发起请求时带上 If-Modified-Since 时间,服务器收到新请求后发现有 If-Modified-Since 字段,则与被请求资源的最后修改时间(Last-Modified)进行对比,如果最后修改时间更大(服务器资源更新),说明资源被修改过,则返回最新资源且响应 HTTP 200 OK;反之说明资源无更新修改,响应 HTTP 304,客户端调取本地缓存
- 通过响应头中的
ETag字段和请求头中的If-None-Match字段实现,这两个字段的意思是:
- 响应头中的
ETag唯一标识响应资源 - 请求头中的
If-None-Match,当本地资源过期后,客户端发现响应头里有 ETag ,则再次向服务端发起请求时会将请求头的 If-None-Match 字段设为 ETag 的值。服务器收到新的请求后将请求头中的 ETag 和资源的 ETag 比对,如果资源没有发生变化则响应304,反之则返回新的资源和响应200。
方法1基于时间实现,方法2基于唯一标识实现。相对来说方法2能够更准确地判断是否资源是否被修改。现实使用中也是这样,第一次请求资源时,如返回的 HTTP 响应头同时有 Last-Modified 和 ETag 字段,那么客户端再次发起请求时就会将 ETag 和 If-Modified-Since 都带上,服务端则会先判断 ETag 是否变化,即 ETag 优先级更高。原因是:
- 没有修改资源内容的情况下,资源的最后修改时间也可能改变,这会导致客户端认为该资源被改动了,从而重新请求。
- If-Modified-Since 的检查粒度是秒级,有些资源内容是在秒级以内修改的,使用 ETag 就能保证客户端在一秒内刷新多次的需求的实现。
- 有些服务器不能精确获取资源的最后修改时间。
协商缓存无论使用什么方式都要配合强制缓存的 Cache-Control 字段使用,只有在强制缓存未命中的时候,才能发起才有协商缓存字段的请求。
HTTP/1.1 的优缺点?
- 优点
- 简单:报文格式
header+body,头部信息格式key-value,易理解、学习和使用。 - 灵活(易拓展):HTTP工作在应用层,其下层可以按需改变,例如HTTPS协议就是在HHTP和TCP层之间增加了SSL/TLS安全传输层。
- 应用广泛可跨平台:HTTP应用非常广泛,从浏览器到移动端APP,到网购、网游、线上交易系统等等都有HTTP的应用,且天然具有跨平台的特性。
- 简单:报文格式
- 双刃剑
- 无状态:服务器不会去记忆HTTP的状态,所以不需要额外的资源来记录状态信息,可以减少服务器的资源消耗;因为服务器不会去记忆HTTP的状态,所以在有关联性的操作上就会很麻烦,例如你点进一个网站,每切换一次界面就要你登录一次,那使用体验会非常差。这个缺点可以使用
Cookie技术解决。 - 明文传输:便于阅读内容和抓包分析,有利于调试工作;同样我们的信息无论隐私与否都会直接暴露。
- 无状态:服务器不会去记忆HTTP的状态,所以不需要额外的资源来记录状态信息,可以减少服务器的资源消耗;因为服务器不会去记忆HTTP的状态,所以在有关联性的操作上就会很麻烦,例如你点进一个网站,每切换一次界面就要你登录一次,那使用体验会非常差。这个缺点可以使用
- 缺点
- 不安全:明文传输,信息可能会被窃取;不验证通信方身份,可能遭遇伪装,例如各种钓鱼网站;无法验明报文完整性,所以信息可能遭到篡改。HTTP的安全问题可以通过引入SSL/TLS层解决,即HTTPS协议。
了解网络编程协议吗?客户端发送给服务器的请求,怎么确定具体的协议?
客户端发送给服务器的请求,可以根据统一资源定位系统(Uniform Resource Locator, URL)来确定具体使用的协议。
一个完整的URL包括——协议部分、网址、文件地址部分。协议部分以//为分隔符,在internet中,我们可以使用多种协议: HTTP——Hypertext Transfer Protocal(超文本传输协议) FTP——File Transfer Protocal(文件传输协议) Gopher——The Internet Gopher Protocal(网际Gopher协议) File——本地文件传输协议 HTTPS——安全套接字层超文本传输协议(HTTP的安全版)
介绍一下TCP协议
- TCP协议的特性:TCP协议是面向连接的,提供全双工的服务,数据流可以双向传输。也是点对点的,即在单个发送方和单个接收方之间的连接。
- TCP报文段结构
- 序号:TCP的序号是数据流中的字节数,不是分组的序号。表示该报文段数据字段首字节的序号。
- 确认号:TCP使用累计确认,确认号是第一个未收到的字节序号,表示希望接收到的下一个字节。
- 首部长度:通常选项字段为空,所以一般TCP首部的长度是20字节。
- 选项字段(可选的、变长的):用于发送方与接收方协商MSS(最大报文段长),或在高速网络环境下用作窗口调节因子。
- 标志字段:
- ACK:指示确认字段中的值是有效的
- RST, SYN, FIN:连接建立与拆除
- PSH:指示接受方应立即将数据交给上层
- URG:报文段中存在着(被发送方的上层实体位置)“紧急”的数据
- 接收窗口:用于流量控制(表示接收方还有多少可用的缓存空间)。
- 流量控制:如果应用程序读取数据相当慢,而发送方发送数据太多、太快,会很容易使接收方的接收缓存溢出,流量控制就是用来进行发送速度和接收速度的匹配。发送方维护一个“接收窗口”变量,这个变量表示接收方当前可用的缓存空间。
说一说TCP/IP协议
- TCP/IP协议定义:Transmission Control Protocal/Internet Protocal, 传输控制协议/网际协议,是指能够在多个不同网络之间实现信息传输的协议簇。TCP/IP协议不仅仅指TCP和IP两个协议,而是指一个包含但不限于FTP、SMTP、TCP、UDP、IP等协议构成的协议簇,只是因为在TCP/IP协议中TCP协议和IP协议最具代表性,所以被称为TCP/IP协议。
- TCP/IP协议组成:TCP/IP结构模型分为 应用层、传输层、网络层、链路层(网络接口层) 四层,以下是各层的详细介绍:
- 应用层:应用层是TCP/IP协议的第一层,是直接为应用进程提供服务的。
- 对不同种类的应用程序它们会根据自己的需要来使用应用层的不同协议,邮件传输应用使用了SMTP协议、万维网应用使用了HTTP协议、远程登录服务应用使用了TELNET协议。
- 应用层还是能加密、解密、格式化数据。
- 应用层可以建立或解除与其他节点的联系,这样可以充分节省网络资源。
- 传输层:作为TCP/IP协议的第二层,传输层在整个TCP/IP协议中起到了中流砥柱的作用,而在传输层中,TCP和UDP又起到了中流砥柱的作用。
- 网络层:位于TCP/IP协议中的第三层。在TCP/IP协议中网络层可以进行网络连接的建立和终止以及IP地址的寻找等功能。
- 链路层(网络接口层):位于TCP/IP协议的第四层,由于网络接口层兼并了物理层和数据链路层。所以,网络接口层既是传输数据的物理媒介,也可以为网络层提供一条准确无误的路线。
- 应用层:应用层是TCP/IP协议的第一层,是直接为应用进程提供服务的。
- TCP/IP协议特点:TCP/IP协议能够迅速发展并成为事实上的标准,是因为它恰好适应了世界范围内数据通信的需要。它有以下特点:
- 协议标准完全开放,可供用户免费使用,并且独立于特定的计算机硬件与操作系统;
- 独立于网络硬件系统,可以运行在广域网,更适合于互联网;
- 网络地址统一分配,网络中每一种设备和终端都具有一个唯一地址;
- 高层协议标准化,可以提供多种多样的可靠网络服务。
说一下TCP的三次握手
- 第一次握手:建立连接时,客户端发送syn包(syn=x),并进入SYN_SENT状态,等待服务器确认;SYN:同步序列编号(Synchronize Sequence Numbers);
- 第二次握手:服务器收到syn包,必须确认客户的SYN(ack=x+1),同时自己也发送一个SYN包(syn=y),即SYN+ACK包,此时服务器进入SYN_RECV状态;
- 第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包(ack=y+1),此包发送完毕,客户端和服务器进入ESTABLISHED(TCP连接成功)状态,完成三次握手。 以下是图示:
说一下TCP的四次挥手,以及为什么需要四次挥手?
- 客户端进程发出连接释放报文,并且停止发送数据。释放数据报文首部,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(最大报文段寿命)的时间后,才进入CLOSED状态。服务器只要收到了客户端发出的确认则立即进入CLOSED状态。可以看出,服务器结束TCP连接的时间比客户端要早一点。 以下是图示:
TCP协议是一种面向连接的、可靠的、基于字节流的传输层通信协议。TCP是全双工模式,这就意味着,当客户端发出FIN报文时,只是表示客户端已经没有数据要发送了,客户端告诉服务器,它的数据已经全部发送完毕;但是这个时候客户端还可以接收来自服务器的数据,当服务器返回ACK报文段时,表示服务器已经知道客户端没有数据要发送了,但是服务器还可以发送数据给客户端;当服务器也发送了FIN报文段时,这个时候就表示服务器也没有数据要发送了,就会告诉客户端,然后彼此就会结束这次TCP连接。
即前两次挥手是关闭客户端向服务器的通道,后两次挥手则是关闭服务器向客户端的通道。
如何实现一个可靠的UDP?
为什么需要可靠的UDP?
在弱网(2G、3G、信号不好)环境下,使用TCP连接的延迟很高,影响体验。使用UDP是很好的解决方案。既然要把UDP作为弱网下的TCP来使用,就必须保证数据传输能像TCP一样可靠。
如何实现
UDP不属于连接型协议,因而具有消耗资源小、处理速度快等优点,所以通常在传输音频、视频和普通数据时使用UDP较多,因为这些数据即使偶尔丢失一两个数据包也不会对接收结果产生太大的影响。传输层使用UDP无法保证数据的可靠传输,就只能通过应用层来实现了。实现的方式可以参照TCP可靠性传输的方式,只不过把实现转移到了应用层。关键在于两点:
- 提供超时重传,能够避免数据丢失;
- 提供确认序列号,可以对数据报进行确认和排序。
本端:首先在UDP数据报定义一个首部,首部包含确认序列号和时间戳,时间戳是用来计算RTT(数据报传输的往返时间),计算出合适的RTO(重传的超时时间。)然后以等-停的方式发送数据报,即收到对端的确认后才发送下一个的数据报。当时间超时,本端重传数据报,同时RTO扩大为原来的两倍,重新开始计时。
对端:接收到一个数据报之后取下该数据报首部的时间戳和确认序列号,并添加本端的确认数据报首部之后发送给对端。根据此序列号对已收到的数据报进行排序并丢弃重复的数据报。
已实现的可靠UDP
RUDP可靠数据报传输协议;RTP实时传输协议:为数据提供了具有实时特征的端对端传输服务,例如:组播或单播网络服务下的交互式视频、音频或模拟数据;UDT基于UDP的数据传输协议,是一种互联网传输协议,主要目的是支持高速广域网上的海量数据传输,引入了新的拥塞控制和数据可靠性控制机制(互联网上的标准数据传输协议TCP在高带宽长距离的网络上性能很差)。UDT是面向连接的双向的应用层协议,同时支持可靠的数据流传输和部分可靠的数据报服务,应用如:高速数据传输,点对点技术(P2P),防火墙穿透,多媒体数据传输。
HTTP2.0中TCP阻塞了怎么办?
阻塞类型:
- TCP队头阻塞:TCP数据报是有序传输,中间一个数据报丢失,会等待该数据包重传,造成后面的数据包的阻塞。
- HTTP队头阻塞:和TCP队头阻塞不是一回事。HTTP1.x采用长连接(Connection: keep-alive),可以在一个TCP连接上,发送多个HTTP请求。有非管道化和管道化两种方式:
- 非管道化:完全串行执行,请求->响应->请求->响应->...,后一个请求必须在前一个响应之后发送。
- 管道化:请求可以并行发出,但是响应必须串行返回。后一个响应必须在前一个响应之后。因为没有序号标明顺序,只能串行接收。
管道化请求的致命弱点:
- 会造成队头阻塞,前一个响应未及时返回,后面的响应被阻塞;
- 请求必须是幂等请求,不能修改资源(安全请求)。否则意外中断时,客户端需要把未收到响应的请求重发,非幂等请求会造成资源破坏。 基于这些原因,目前大部分的浏览器和Web服务器都关闭了管道化,采用非管道化模式。无论是非管道化还是管道化都会造成队头阻塞。
解决HTTP队头阻塞的方法:
- 并发TCP连接(浏览器一个域名采用6-8个TCP连接,并发HTTP请求);
- 域名分片(多个域名,可以建立更多的TCP连接,从而提高HTTP请求的并发)。
HTTP2.0方式:HTTP2使用一个域名单一TCP连接发送请求,请求包被二进制分帧,不同请求可以互相穿插,避免了HTTP层面的请求队头阻塞,但不能避免TCP层面的队头阻塞。
说一下TCP里的reset状态
TCP异常终止(reset报文):TCP的异常终止是相对于正常释放TCP连接的过程而言的。我们都知道TCP连接的建立是通过三次握手完成的,而TCP正常释放丽娜姐是通过四次挥手来完成。但在一些特殊情况下,TCP在交互的过程中会出现一些意想不到的情况,导致TCP无法按照正常的四次挥手来释放连接,如果此时不通过其他方法释放TCP连接的话,这个TCP连接会一直存在,占用系统的部分资源。在这种情况下,我们需要有一种能够释放TCP连接的机制,这种机制就是TCP的reset报文,指的是TCP包头的标志字段中的reset位置的报文。
RST标志位:RST表示复位,用来异常地关闭连接,在TCP的设计中它是不可或缺的。发送RST包关闭连接时,不必等缓冲区的包都发出去(不同于FIN包),直接丢弃缓存区的包并发送RST包。而接收端收到RST包后,也不必发送ACK包来确认。
TCP程序会在自己认为异常的时刻发送RST包。例如,A向B发起连接,但B之上并未监听相应的端口,这时B操作系统上的TCP处理程序会发送RST包。又例如,A和B正常建立了连接,正在通讯时,A向B发送了FIN包要求关闭连接,B发送ACK之后,网断了,A通过若干手段放弃了这个连接(例如进程重启)。网通了之后,B又开始发数据包,A收到后表示压力很大,不知道这连接哪来的,就发了个RST包强制把连接关了,B收到后会出现connect reset by peer错误。
常见的TCP异常终止情况:
- 客户端尝试与服务器未对外提供服务的端口建立TCP连接,服务器将会直接向客户端发送reset报文;
- 客户端和服务器的某一方在交互过程中发生异常(如程序崩溃等),该方系统将会向对方发送TCP reset报文,告知对方释放相关的TCP连接。
- 接收端收到TCP报文,但是发现该TCP的报文并不在其已建立的TCP连接列表内,则其直接向对端发送reset报文。
- 在交互的双方中的某一方长期未收到来自对方的确认报文,则其在超出一定的重传次数或时间后,会主动向对端发送reset报文释放该TCP连接。
- 有些应用开发者在设计应用系统时,会利用reset报文快速释放已经完成数据交互的TCP连接,以提高业务交互的效率。
说一说对IP分类的了解
IP地址根据网络号和主机号来分,分为A、B、C三类及特殊地址D、E。 全0和全1的都保留不用。
- A类:(1.0.0.0-126.0.0.0)(默认子网掩码:255.0.0.0或 0xFF000000)第一个字节为网络号,后三个字节为主机号。该类IP地址的最前面为“0”,所以地址的网络号取值于1~126之间。一般用于大型网络。
- B类:(128.0.0.0-191.255.0.0)(默认子网掩码:255.255.0.0或0xFFFF0000)前两个字节为网络号,后两个字节为主机号。该类IP地址的最前面为“10”,所以地址的网络号取值于128~191之间。一般用于中等规模网络。
- C类:(192.0.0.0-223.255.255.0)(子网掩码:255.255.255.0或 0xFFFFFF00)前三个字节为网络号,最后一个字节为主机号。该类IP地址的最前面为“110”,所以地址的网络号取值于192~223之间。一般用于小型网络。
- D类:是多播地址。该类IP地址的最前面为“1110”,所以地址的网络号取值于224~239之间。一般用于多路广播用户 。
- E类:是保留地址。该类IP地址的最前面为“1111”,所以地址的网络号取值于240~255之间。
以下是图示:
IP为什么要分类?
根据IP地址访问终端是通过路由器,路由设备当中有一张路由表,该路由表记录了所有IP地址的位置,这样就可以进行包的转发了,如果我们不区分网络地址,那么这张路由表当中就要保存所有IP地址的方向,这张路由表就会很大。即如果不分网络位和主机位,路由器的路由表就是都是32位地址,那所有的路由器维护的路由表就会很大,转发速度会变慢(因为查询变慢)。而且所有的路由器都要有全Internet的地址,所有人的路由器都要有足够的性能来存下全网地址。建造这样的Internet的成本会是现在的几万倍甚至更高。
说一下HTTPS的混合加密
使用非对称加密耗时,对称加密不安全(密钥明文传输的过程中易被截取)。所以HTTPS采用了混合加密的方式,并且尽量减少非对称加密的次数,以下是混合加密过程:
- 某服务器拥有用于非对称加密的公钥
A和私钥A'; - 浏览器向服务器请求,服务器把公钥
A明文传输给浏览器; - 浏览器随机生成一个用于对称加密的密钥
X,用公钥A加密后传给服务器; - 服务器拿到后用私钥
A'解密得到密钥X; - 这样双方就都拥有密钥
X了,且别人无法知道它,之后双方所有数据都用密钥X加解密。 HTTPS基本上就是使用上述混合加密方案,其中非对称加解密只需各用一次。
HTTPS支持什么加密算法?
常见的对称加密算法有:DES、3DES、Blowfish、IDEA、RC4、RC5、RC6和AES ;
常见的非对称加密算法有:RSA、ECC(移动设备用)、Diffie-Hellman、El Gamal、DSA(数字签名用);
常见的Hash算法有:MD2、MD4、MD5、HAVAL、SHA;
HTTP1.1和HTTP2.0有什么区别?
-
HTTP2.0使用了多路复用技术,做到同一个连接并发处理多个请求,而且并发请求的数量比HTTP1.1大了好几个数量级。HTTP1.1也可以多建立几个TCP连接,来支持处理更多的并发请求,但是创建TCP连接本身也是有开销的。
-
在HTTP1.1中,HTTP请求和响应都是由状态行、请求/响应头部、消息主体三部分组成。一般而言,消息主体都会经过gzip压缩,或者本身传输的就是压缩过后的二进制文件,但状态行和头部却没有经过任何压缩,直接以纯文本传输。随着Web功能越来越复杂,每个页面产生的请求数据也越来越多,导致消耗在头部的流量越来越多,尤其是每次都要传输UserAgent, Cookie这类不会频繁变动的内容,完全是一种资源浪费。HTTP1.1不支持header数据的压缩,HTTP2.0使用HPACK算法对header的数据进行压缩,这样数据体积小了,在网络上传输就会更快。
-
服务端推送是一种在客户端请求之前发送数据的机制。网页使用了许多资源:HTML、样式表、脚本、图片等等。在HTTP1.1中这些资源每一个都必须明确地请求。这是一个很慢的过程。浏览器从获取HTML开始,然后在它解析和评估页面的时候,增量地获取更多的资源。因为服务器必须等待浏览器做每一个请求,网络经常是空闲和未充分使用的。为了改善延迟,HTTP2.0引入了server push,它允许服务端推送资源给客户端,在客户端明确地请求之前,免得客户端再次创建连接发送请求到服务端获取。这样客户端可以直接从本地加载这些资源,不用再通过网络。
HTTP2.0和HTTP3.0有什么区别?
HTTP2.0使用TCP协议,HTTP3.0使用UDP协议。
各版本之间的HTTP有什么不同?
HTTP0.9 最简单的只有请求行 GET index.html
HTTP1.0
- 增加请求头、响应头,使得请求和响应都更加清晰;
- 增加状态码,让响应更清晰;
- 增加缓存功能,已请求过的内容再次请求时就可以直接使用缓存。
GET index.html HTTP/1.0 accept: application/html accept-charset: utf-8 accept-encoding: gzip accept-language: zh-CN
HTTP/1.0 200 OK
<!DOCTYPE html>
<html>
<head></head>
<body>hello world!</body>
</html>
accept 解决文件格式问题,是json还是html,浏览器根据不同文件格式来解析文件; accept-charset 解决文件编码问题,告知浏览器如何将字符流解析成字节流; accept-encoding 解决大文件压缩问题,浏览器采用指定的解压方式来解压; accept-language 解决国际化问题,不同国家请求不同语言的文件。
HTTP1.1
- 持久连接,多个HTTP请求使用同一个TCP连接,减少了TCP建立连接时的开销;
- 客户端和服务器之间可以建立多个TCP连接以解决队头阻塞的问题;
- 响应体可以分块传输,无需一次传输全部内容;
- 响应头增加了content-length字段满足动态内容无法一次计算出长度和无法一次传输完成的问题;
- 增加了安全机制和cookie机制
HTTP2.0实现了多路复用,客户端和服务器之间只建立一条TCP连接,每个HTTP请求被切分成多帧,多个HTTP的帧混合在一起在一个TCP连接上传输。
HTTP3.0不再使用TCP协议,因为TCP无论如何优化依然是顺序发送、顺序接收的,依然会有队头阻塞问题,更换传输层协议才能解决队头阻塞问题。例如Google的QUIC就使用了UDP协议。
介绍socket通信的具体步骤
sockets(套接字)编程有三种:流式套接字(SOCK_STREAM)、数据报套接字(SOCK_DGRAM)、原始套接字(SOCK_RAW)。 基于TCP的socket编程采用的是流式套接字。
服务器端编程的步骤:
- 加载套接字库,创建套接字(WSAStartup()/socket());
- 绑定套接字到一个IP地址和一个端口上(bind());
- 将套接字设置为监听模式等待连接请求(listen());
- 请求到来后,接受连接请求,返回一个新的对应于此次连接的套接字(accept());
- 用返回的套接字和客户端进行通信(send()/recv());
- 返回,等待另一连接请求;
- 关闭套接字,关闭加载的套接字库(WSACleanup()/colsesocket())。
客户端编程的步骤:
- 加载套接字库,创建套接字(WSAStartup()/socket());
- 向服务器发出连接请求(connect());
- 和服务器端进行通信(send()/recv());
- 关闭套接字,关闭加载的套接字库(WSACleanup()/closesocket())。