跳到主要内容

DNS协议 是什么?说说DNS 完整的查询过程?

一、DNS协议是什么?

DNS(Domain Name System),域名系统,是互联网中的一项服务,用于将域名(例如www.example.com)解析为对应的IP地址(例如192.0.2.1)。DNS相当于一个翻译官,负责将人类可读的域名翻译成计算机可理解的IP地址,从而实现网络通信。

在计算机网络中,数据通信的核心是IP地址,但是IP地址是一串数字,不方便人们记忆和使用。因此,DNS就像一个电话簿一样,通过域名来查找相应的IP地址,使得人们可以使用便于记忆的域名来访问网站,而不必记住复杂的IP地址。

二、域名结构

域名是一个具有层次结构的标识系统,由一系列以点分隔的名字组成。从右向左,域名的层级结构由低级到高级,例如:www.example.com,其中.com为顶级域名,example为二级域名,www为三级域名。

域名系统的结构如下图所示:

. (根域名)
|
|-- com (顶级域名)
| |
| |-- example (二级域名)
| |
| |-- www (三级域名)
| |
| |-- ... (更多子域名)
|
|-- net (顶级域名)
| |
| |-- ...
|
|-- org (顶级域名)
| |
| |-- ...
|
... (更多顶级域名)

三、DNS查询的方式

DNS查询的方式有两种:

1. 递归查询

递归查询是一种由客户端向DNS服务器发起的查询方式,客户端会一直迭代查询直至得到最终的查询结果。在递归查询中,如果目标DNS服务器不知道某个域名的IP地址,它会向其他DNS服务器发起请求,直到找到能够解析该域名的DNS服务器为止。

2. 迭代查询

迭代查询是一种DNS服务器之间的查询方式,DNS服务器之间会相互请求信息,但不会一直迭代查询直至得到最终结果。每个DNS服务器只会返回下一级的DNS服务器地址给客户端,让客户端继续查询。

四、域名缓存

DNS查询过程中,为了减少查询时间和减轻DNS服务器负担,会在客户端和DNS服务器上设置缓存。查询过的域名和对应的IP地址会被缓存一段时间,以便下次查询时可以直接使用缓存结果,加快查询速度。

客户端和DNS服务器的缓存分别为:

  • 浏览器缓存:浏览器在获取网站域名的实际IP地址后会对其进行缓存,减少网络请求的损耗。

  • 操作系统缓存:操作系统的缓存其实是用户自己配置的 hosts 文件,可以手动添加一些常用域名和对应的IP地址,避免每次都进行DNS查询。

五、完整的DNS查询过程

下面是一个完整的DNS查询过程:

  1. 首先搜索浏览器的DNS缓存,如果存在目标域名的缓存结果,则直接返回IP地址,查询结束。

  2. 如果浏览器缓存中没有目标域名的结果,继续搜索操作系统的DNS缓存,如果存在目标域名的缓存结果,则直接返回IP地址,查询结束。

  3. 如果操作系统缓存中没有目标域名的结果,将域名发送给本地域名服务器。

  4. 本地域名服务器首先搜索自己的缓存,如果存在目标域名的缓存结果,则直接返回IP地址,查询结束。

  5. 如果本地域名服务器的缓存中没有目标域名的结果,本地域名服务器会按照递归查询的方式,向更高级的DNS服务器发起请求。

  6. 递归查询中,如果某个DNS服务器无法解析目标域名,则该DNS服务器会向更高级的DNS服务器请求解析结果,直至找到能够解析目标域名的DNS服务器。

  7. 最终,本地域名服务器得到目标域名对应的IP地址,并将IP地址返回给操作系统,并缓存该结果。

  8. 操作系统将IP地址返回给浏览器,并缓存该结果。

  9. 浏览器得到目标域名对应的IP地址,开始与服务器建立连接,进行后续的网络通信。

整个DNS查询过程涉及多个级别的DNS服务器的协作和查询,直至找到目标域名对应的IP地址。

六、DNS查询过程中的代码示例

下面是一个使用Python编写的简单DNS查询的代码示例,使用socket库进行DNS查询:

const dns = require('dns');

function dnsLookup(domain) {
return new Promise((resolve, reject) => {
dns.lookup(domain, (err, address, family) => {
if (err) {
reject(err);
} else {
resolve(address);
}
});
});
}

const domainName = 'www.example.com';
dnsLookup(domainName)
.then(ipAddress => {
console.log(`The IP address of ${domainName} is ${ipAddress}`);
})
.catch(error => {
console.error(`DNS lookup failed: ${error.message}`);
});

在这个示例中,我们定义了一个dns_lookup函数来进行DNS查询,传入域名作为参数,然后使用socket.gethostbyname()函数来获取域名对应的IP地址。如果查询失败,会捕获socket.gaierror异常,并返回相应的错误信息。

参考文献

为什么说HTTPS比HTTP安全? HTTPS是如何保证安全的?

一、安全特性

在上篇文章中,我们了解到HTTP在通信过程中,存在以下问题:

  • 通信使用明文(不加密),内容可能被窃听
  • 不验证通信方的身份,因此有可能遭遇伪装

HTTPS的出现正是解决这些问题,HTTPS是建立在SSL之上,其安全性由SSL来保证

在采用SSL后,HTTP就拥有了HTTPS的加密、证书和完整性保护这些功能

SSL(Secure Sockets Layer 安全套接字协议),及其继任者传输层安全(Transport Layer Security,TLS)是为网络通信提供安全及数据完整性的一种安全协议

image

二、如何做

SSL 的实现这些功能主要依赖于三种手段:

  • 对称加密:采用协商的密钥对数据加密
  • 非对称加密:实现身份认证和密钥协商
  • 摘要算法:验证信息的完整性
  • 数字签名:身份验证

对称加密

对称加密指的是加密和解密使用的秘钥都是同一个,是对称的。只要保证了密钥的安全,那整个通信过程就可以说具有了机密性

image

非对称加密

非对称加密,存在两个秘钥,一个叫公钥,一个叫私钥。两个秘钥是不同的,公钥可以公开给任何人使用,私钥则需要保密

公钥和私钥都可以用来加密解密,但公钥加密后只能用私钥解 密,反过来,私钥加密后也只能用公钥解密

image

混合加密

HTTPS通信过程中,采用的是对称加密+非对称加密,也就是混合加密

在对称加密中讲到,如果能够保证了密钥的安全,那整个通信过程就可以说具有了机密性

HTTPS采用非对称加密解决秘钥交换的问题

具体做法是发送密文的一方使用对方的公钥进行加密处理“对称的密钥”,然后对方用自己的私钥解密拿到“对称的密钥”

image

这样可以确保交换的密钥是安全的前提下,使用对称加密方式进行通信

举个例子:

网站秘密保管私钥,在网上任意分发公钥,你想要登录网站只要用公钥加密就行了,密文只能由私钥持有者才能解密。而黑客因为没有私钥,所以就无法破解密文

上述的方法解决了数据加密,在网络传输过程中,数据有可能被篡改,并且黑客可以伪造身份发布公钥,如果你获取到假的公钥,那么混合加密也并无多大用处,你的数据扔被黑客解决

因此,在上述加密的基础上仍需加上完整性、身份验证的特性,来实现真正的安全,实现这一功能则是摘要算法

摘要算法

实现完整性的手段主要是摘要算法,也就是常说的散列函数、哈希函数

可以理解成一种特殊的压缩算法,它能够把任意长度的数据“压缩”成固定长度、而且独一无二的“摘要”字符串,就好像是给这段数据生成了一个数字“指纹”

image

摘要算法保证了“数字摘要”和原文是完全等价的。所以,我们只要在原文后附上它的摘要,就能够保证数据的完整性

比如,你发了条消息:“转账 1000 元”,然后再加上一个 SHA-2 的摘要。网站收到后也计算一下消息的摘要,把这两份“指纹”做个对比,如果一致,就说明消息是完整可信的,没有被修改

image

数字签名

数字签名能确定消息确实是由发送方签名并发出来的,因为别人假冒不了发送方的签名

原理其实很简单,就是用私钥加密,公钥解密

签名和公钥一样完全公开,任何人都可以获取。但这个签名只有用私钥对应的公钥才能解开,拿到摘要后,再比对原文验证完整性,就可以像签署文件一样证明消息确实是你发的

image

和消息本身一样,因为谁都可以发布公钥,我们还缺少防止黑客伪造公钥的手段,也就是说,怎么判断这个公钥就是你的公钥

这时候就需要一个第三方,就是证书验证机构

CA验证机构

数字证书认证机构处于客户端与服务器双方都可信赖的第三方机构的立场

CA 对公钥的签名认证要求包括序列号、用途、颁发者、有效时间等等,把这些打成一个包再签名,完整地证明公钥关联的各种信息,形成“数字证书”

流程如下图:

image

  • 服务器的运营人员向数字证书认证机构提出公开密钥的申请
  • 数字证书认证机构在判明提出申请者的身份之后,会对已申请的公开密钥做数字签名
  • 然后分配这个已签名的公开密钥,并将该公开密钥放入公钥证书后绑定在一起
  • 服务器会将这份由数字证书认证机构颁发的数字证书发送给客户端,以进行非对称加密方式通信

接到证书的客户端可使用数字证书认证机构的公开密钥,对那张证书上的数字签名进行验证,一旦验证通过,则证明:

  • 认证服务器的公开密钥的是真实有效的数字证书认证机构
  • 服务器的公开密钥是值得信赖的

三、总结

可以看到,HTTPSHTTP虽然只差一个SSL,但是通信安全得到了大大的保障,通信的四大特性都以解决,解决方式如下:

  • 机密性:混合算法
  • 完整性:摘要算法
  • 身份认证:数字签名
  • 不可否定:数字签名

同时引入第三方证书机构,确保公开秘钥的安全性

参考文献

什么是HTTP? HTTP 和 HTTPS 的区别?

一、HTTP

HTTP (HyperText Transfer Protocol),即超文本运输协议,是实现网络通信的一种规范

image

在计算机和网络世界有,存在不同的协议,如广播协议、寻址协议、路由协议等等......

HTTP是一个传输协议,即将数据由A传到B或将B传输到A,并且 A 与 B 之间能够存放很多第三方,如: A<=>X<=>Y<=>Z<=>B

传输的数据并不是计算机底层中的二进制包,而是完整的、有意义的数据,如HTML 文件, 图片文件, 查询结果等超文本,能够被上层应用识别

在实际应用中,HTTP常被用于在Web浏览器和网站服务器之间传递信息,以明文方式发送内容,不提供任何方式的数据加密

特点如下:

  • 支持客户/服务器模式

  • 简单快速:客户向服务器请求服务时,只需传送请求方法和路径。由于HTTP协议简单,使得HTTP服务器的程序规模小,因而通信速度很快

  • 灵活:HTTP允许传输任意类型的数据对象。正在传输的类型由Content-Type加以标记

  • 无连接:无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间

  • 无状态:HTTP协议无法根据之前的状态进行本次的请求处理

二、HTTPS

在上述介绍HTTP中,了解到HTTP传递信息是以明文的形式发送内容,这并不安全。而HTTPS出现正是为了解决HTTP不安全的特性

为了保证这些隐私数据能加密传输,让HTTP运行安全的SSL/TLS协议上,即 HTTPS = HTTP + SSL/TLS,通过 SSL证书来验证服务器的身份,并为浏览器和服务器之间的通信进行加密

SSL 协议位于 TCP/IP 协议与各种应用层协议之间,浏览器和服务器在使用 SSL 建立连接时需要选择一组恰当的加密算法来实现安全通信,为数据通讯提供安全支持

image

流程图如下所示:

image

  • 首先客户端通过URL访问服务器建立SSL连接
  • 服务端收到客户端请求后,会将网站支持的证书信息(证书中包含公钥)传送一份给客户端
  • 客户端的服务器开始协商SSL连接的安全等级,也就是信息加密的等级
  • 客户端的浏览器根据双方同意的安全等级,建立会话密钥,然后利用网站的公钥将会话密钥加密,并传送给网站
  • 服务器利用自己的私钥解密出会话密钥
  • 服务器利用会话密钥加密与客户端之间的通信

三、区别

  • HTTPS是HTTP协议的安全版本,HTTP协议的数据传输是明文的,是不安全的,HTTPS使用了SSL/TLS协议进行了加密处理,相对更安全
  • HTTP 和 HTTPS 使用连接方式不同,默认端口也不一样,HTTP是80,HTTPS是443
  • HTTPS 由于需要设计加密以及多次握手,性能方面不如 HTTP
  • HTTPS需要SSL,SSL 证书需要钱,功能越强大的证书费用越高

参考文献

如何理解CDN?说说实现原理?

一、CDN是什么?

CDN (全称 Content Delivery Network),即内容分发网络。

CDN是构建在现有网络基础之上的智能虚拟网络,通过部署在各地的边缘服务器,通过中心平台的负载均衡、内容分发、调度等功能模块,使用户能够就近获取所需内容,从而降低网络拥塞,提高用户访问响应速度和命中率。CDN的关键技术主要有内容存储和分发技术。

简单来说,CDN就是根据用户位置分配最近的资源,让用户在上网的时候不用直接访问源站,而是访问离他“最近的”一个CDN节点,该节点其实是缓存了源站内容的代理服务器。如下图所示:

二、CDN实现原理

在没有应用CDN时,我们使用域名访问某个站点的路径为:

用户提交域名→浏览器对域名进行解释→DNS解析得到目的主机的IP地址→根据IP地址发出请求→得到请求数据并回复

应用CDN后,DNS解析不再返回IP地址,而是一个CNAME (Canonical Name) 别名记录,指向CDN的全局负载均衡。

CNAME实际上在域名解析的过程中承担了中间人(或者说代理)的角色,这是CDN实现的关键。

负载均衡系统

由于没有返回IP地址,本地DNS会向负载均衡系统发送请求,然后进入CDN的全局负载均衡系统进行智能调度:

  • 看用户的IP地址,查表得知地理位置,找相对最近的边缘节点。
  • 看用户所在的运营商网络,找相同网络的边缘节点。
  • 检查边缘节点的负载情况,找负载较轻的节点。
  • 其他因素,如节点的“健康状况”、服务能力、带宽、响应时间等。

综合上述因素,找到最合适的边缘节点,然后将该节点返回给用户,用户就能够就近访问CDN的缓存代理。

整体流程如下图所示:

image

缓存代理

缓存系统是CDN的另一个关键组成部分,缓存系统会有选择地缓存那些最常用的资源。

其中有两个衡量CDN服务质量的指标:

  • 命中率:用户访问的资源恰好在缓存系统里,可以直接返回给用户,命中次数与所有访问次数之比。
  • 回源率:缓存里没有,必须用代理的方式回源站取,回源次数与所有访问次数之比。

缓存系统也可以划分成层次,分为一级缓存节点和二级缓存节点。一级缓存配置高一些,直连源站,二级缓存配置低一些,直连用户。

回源的时候二级缓存只找一级缓存,一级缓存没有才回源站,这样可以有效地减少真正的回源。

现在的商业CDN命中率通常在90%以上,相当于把源站的服务能力放大了10倍以上。

三、总结

CDN的目的是为了改善互联网的服务质量,通俗一点说其实就是提高访问速度。

CDN构建了全国、全球级别的专网,让用户就近访问专网里的边缘节点,降低了传输延迟,实现了网站加速。

通过CDN的负载均衡系统,智能调度边缘节点提供服务,相当于CDN服务的大脑,而缓存系统相当于CDN的心脏,缓存命中直接返回给用户,否则回源。

参考文献

如何理解OSI七层模型?

一、是什么

OSI (Open System Interconnect)模型全称为开放式通信系统互连参考模型,是国际标准化组织 ( ISO ) 提出的一个试图使各种计算机在世界范围内互连为网络的标准框架

OSI 将计算机网络体系结构划分为七层,每一层实现各自的功能和协议,并完成与相邻层的接口通信。即每一层扮演固定的角色,互不打扰

二、划分

OSI主要划分了七层,如下图所示:

image

应用层

应用层位于 OSI 参考模型的第七层,其作用是通过应用程序间的交互来完成特定的网络应用

该层协议定义了应用进程之间的交互规则,通过不同的应用层协议为不同的网络应用提供服务。例如域名系统 DNS,支持万维网应用的 HTTP 协议,电子邮件系统采用的 SMTP 协议等

在应用层交互的数据单元我们称之为报文

表示层

表示层的作用是使通信的应用程序能够解释交换数据的含义,其位于 OSI 参考模型的第六层,向上为应用层提供服务,向下接收来自会话层的服务

该层提供的服务主要包括数据压缩,数据加密以及数据描述,使应用程序不必担心在各台计算机中表示和存储的内部格式差异

会话层

会话层就是负责建立、管理和终止表示层实体之间的通信会话

该层提供了数据交换的定界和同步功能,包括了建立检查点和恢复方案的方法

传输层

传输层的主要任务是为两台主机进程之间的通信提供服务,处理数据包错误、数据包次序,以及其他一些关键传输问题

传输层向高层屏蔽了下层数据通信的细节。因此,它是计算机通信体系结构中关键的一层

其中,主要的传输层协议是TCPUDP

网络层

两台计算机之间传送数据时其通信链路往往不止一条,所传输的信息甚至可能经过很多通信子网

网络层的主要任务就是选择合适的网间路由和交换节点,确保数据按时成功传送

在发送数据时,网络层把传输层产生的报文或用户数据报封装成分组和包,向下传输到数据链路层

在网络层使用的协议是无连接的网际协议(Internet Protocol)和许多路由协议,因此我们通常把该层简单地称为 IP 层

数据链路层

数据链路层通常也叫做链路层,在物理层和网络层之间。两台主机之间的数据传输,总是在一段一段的链路上传送的,这就需要使用专门的链路层协议

在两个相邻节点之间传送数据时,数据链路层将网络层交下来的 IP 数据报组装成帧,在两个相邻节点间的链路上传送帧

每一帧的数据可以分成:报头head和数据data两部分:

  • head 标明数据发送者、接受者、数据类型,如 MAC地址
  • data 存储了计算机之间交互的数据

通过控制信息我们可以知道一个帧的起止比特位置,此外,也能使接收端检测出所收到的帧有无差错,如果发现差错,数据链路层能够简单的丢弃掉这个帧,以避免继续占用网络资源

物理层

作为 OSI 参考模型中最低的一层,物理层的作用是实现计算机节点之间比特流的透明传送

该层的主要任务是确定与传输媒体的接口的一些特性(机械特性、电气特性、功能特性,过程特性)

该层主要是和硬件有关,与软件关系不大

三、传输过程

数据在各层之间的传输如下图所示: image

  • 应用层报文被传送到运输层
  • 在最简单的情况下,运输层收取到报文并附上附加信息,该首部将被接收端的运输层使用
  • 应用层报文和运输层首部信息一道构成了运输层报文段。附加的信息可能包括:允许接收端运输层向上向适当的应用程序交付报文的信息以及差错检测位信息。该信息让接收端能够判断报文中的比特是否在途中已被改变
  • 运输层则向网络层传递该报文段,网络层增加了如源和目的端系统地址等网络层首部信息,生成了网络层数据报
  • 网络层数据报接下来被传递给链路层,在数据链路层数据包添加发送端 MAC 地址和接收端 MAC 地址后被封装成数据帧
  • 在物理层数据帧被封装成比特流,之后通过传输介质传送到对端
  • 对端再一步步解开封装,获取到传送的数据

参考文献

如何理解TCP/IP协议?

一、是什么

TCP/IP,传输控制协议/网际协议,是指能够在多个不同网络间实现信息传输的协议簇

  • TCP(传输控制协议)

一种面向连接的、可靠的、基于字节流的传输层通信协议

  • IP(网际协议)

用于封包交换数据网络的协议

TCP/IP协议不仅仅指的是TCP IP两个协议,而是指一个由FTPSMTPTCPUDPIP等协议构成的协议簇,

只是因为在TCP/IP协议中TCP协议和IP协议最具代表性,所以通称为TCP/IP协议族(英语:TCP/IP Protocol Suite,或TCP/IP Protocols)

二、划分

TCP/IP协议族按层次分别了五层体系或者四层体系

五层体系的协议结构是综合了 OSI 和 TCP/IP 优点的一种协议,包括应用层、传输层、网络层、数据链路层和物理层

五层协议的体系结构只是为介绍网络原理而设计的,实际应用还是 TCP/IP 四层体系结构,包括应用层、传输层、网络层(网际互联层)、网络接口层

如下图所示:

五层体系

应用层

TCP/IP 模型将 OSI 参考模型中的会话层、表示层和应用层的功能合并到一个应用层实现,通过不同的应用层协议为不同的应用提供服务

如:FTPTelnetDNSSMTP

传输层

该层对应于 OSI 参考模型的传输层,为上层实体提供源端到对端主机的通信功能

传输层定义了两个主要协议:传输控制协议(TCP)和用户数据报协议(UDP)

其中面向连接的 TCP 协议保证了数据的传输可靠性,面向无连接的 UDP 协议能够实现数据包简单、快速地传输

网络层

负责为分组网络中的不同主机提供通信服务,并通过选择合适的路由将数据传递到目标主机

在发送数据时,网络层把运输层产生的报文段或用户数据封装成分组或包进行传送

数据链路层

数据链路层在两个相邻节点传输数据时,将网络层交下来的IP数据报组装成帧,在两个相邻节点之间的链路上传送帧

物理层

保数据可以在各种物理媒介上进行传输,为数据的传输提供可靠的环境

四层体系

TCP/IP 的四层结构则如下表所示:

层次名称单位功 能协 议
网络接口层负责实际数据的传输,对应OSI参考模型的下两层HDLC(高级链路控制协议)PPP(点对点协议) SLIP(串行线路接口协议)
网络层数据报负责网络间的寻址数据传输,对应OSI参考模型的第三层IP(网际协议) ICMP(网际控制消息协议)ARP(地址解析协议) RARP(反向地址解析协议)
传输层报文段负责提供可靠的传输服务,对应OSI参考模型的第四层TCP(控制传输协议) UDP(用户数据报协议)
应用层负责实现一切与应用程序相关的功能,对应OSI参考模型的上三层FTP(文件传输协议) HTTP(超文本传输协议) DNS(域名服务器协议)SMTP(简单邮件传输协议)NFS(网络文件系统协议)

三、总结

OSI 参考模型与 TCP/IP 参考模型区别如下:

相同点:

  • OSI 参考模型与 TCP/IP 参考模型都采用了层次结构
  • 都能够提供面向连接和无连接两种通信服务机制

不同点:

  • OSI 采用的七层模型; TCP/IP 是四层或五层结构

  • TCP/IP 参考模型没有对网络接口层进行细分,只是一些概念性的描述; OSI 参考模型对服务和协议做了明确的区分

  • OSI 参考模型虽然网络划分为七层,但实现起来较困难。TCP/IP 参考模型作为一种简化的分层结构是可以的

  • TCP/IP协议去掉表示层和会话层的原因在于会话层、表示层、应用层都是在应用程序内部实现的,最终产出的是一个应用数据包,而应用程序之间是几乎无法实现代码的抽象共享的,这也就造成 OSI 设想中的应用程序维度的分层是无法实现的

三种模型对应关系如下图所示:

参考文献

如何理解UDP 和 TCP? 区别? 应用场景?

一、UDP

UDP(User Datagram Protocol),用户数据包协议,是一个简单的面向数据报的通信协议,即对应用层交下来的报文,不合并,不拆分,只是在其上面加上首部后就交给了下面的网络层

也就是说无论应用层交给UDP多长的报文,它统统发送,一次发送一个报文

而对接收方,接到后直接去除首部,交给上面的应用层就完成任务

UDP报头包括4个字段,每个字段占用2个字节(即16个二进制位),标题短,开销小

image

特点如下:

  • UDP 不提供复杂的控制机制,利用 IP 提供面向无连接的通信服务
  • 传输途中出现丢包,UDP 也不负责重发
  • 当包的到达顺序出现乱序时,UDP没有纠正的功能。
  • 并且它是将应用程序发来的数据在收到的那一刻,立即按照原样发送到网络上的一种机制。即使是出现网络拥堵的情况,UDP 也无法进行流量控制等避免网络拥塞行为

二、TCP

TCP(Transmission Control Protocol),传输控制协议,是一种可靠、面向字节流的通信协议,把上面应用层交下来的数据看成无结构的字节流来发送

可以想象成流水形式的,发送方TCP会将数据放入“蓄水池”(缓存区),等到可以发送的时候就发送,不能发送就等着,TCP会根据当前网络的拥塞状态来确定每个报文段的大小

TCP报文首部有20个字节,额外开销大

image

特点如下:

  • TCP充分地实现了数据传输时各种控制功能,可以进行丢包时的重发控制,还可以对次序乱掉的分包进行顺序控制。而这些在 UDP 中都没有。
  • 此外,TCP 作为一种面向有连接的协议,只有在确认通信对端存在时才会发送数据,从而可以控制通信流量的浪费。
  • 根据 TCP 的这些机制,在 IP 这种无连接的网络上也能够实现高可靠性的通信( 主要通过检验和、序列号、确认应答、重发控制、连接管理以及窗口控制等机制实现)

三、区别

UDPTCP两者的都位于传输层,如下图所示:

两者区别如下表所示:

TCPUDP
可靠性可靠不可靠
连接性面向连接无连接
报文面向字节流面向报文
效率传输效率低传输效率高
双共性全双工一对一、一对多、多对一、多对多
流量控制滑动窗口
拥塞控制慢开始、拥塞避免、快重传、快恢复
传输效率
  • TCP 是面向连接的协议,建立连接3次握手、断开连接四次挥手,UDP是面向无连接,数据传输前后不连接连接,发送端只负责将数据发送到网络,接收端从消息队列读取

  • TCP 提供可靠的服务,传输过程采用流量控制、编号与确认、计时器等手段确保数据无差错,不丢失。UDP 则尽可能传递数据,但不保证传递交付给对方

  • TCP 面向字节流,将应用层报文看成一串无结构的字节流,分解为多个TCP报文段传输后,在目的站重新装配。UDP协议面向报文,不拆分应用层报文,只保留报文边界,一次发送一个报文,接收方去除报文首部后,原封不动将报文交给上层应用

  • TCP 只能点对点全双工通信。UDP 支持一对一、一对多、多对一和多对多的交互通信

两者应用场景如下图:

image

可以看到,TCP 应用场景适用于对效率要求低,对准确性要求高或者要求有链接的场景,而UDP 适用场景为对效率要求高,对准确性要求低的场景

参考文献

说一下 GET 和 POST 的区别?

一、GET和POST是什么?

在HTTP协议中,GET和POST是两种常用的请求方法,用于向服务器发送请求并获取响应。它们有以下特点:

GET方法

GET方法用于请求一个指定资源的表示形式,通常用于获取数据,不应该对服务器产生副作用。GET请求的参数会附加在URL后面。

POST方法

POST方法用于向指定的资源提交要被处理的数据,通常会导致服务器上的状态变化或产生副作用。POST请求的参数会包含在请求的正文中。

二、GET和POST的区别

虽然GET和POST都是使用HTTP协议传输数据,但它们在一些方面有明显的区别:

1. 参数位置

GET请求的参数附加在URL的末尾,形式为:http://example.com/path?param1=value1&param2=value2

POST请求的参数包含在请求的正文中,不会显示在URL中。

2. 数据长度限制

GET请求的参数附加在URL后面,受限于URL的长度限制,一般由浏览器限制,不同浏览器可能有不同的限制,例如IE限制为2083字节。

POST请求的参数在请求的正文中,没有明确的长度限制,一般受到服务器端的配置限制。

3. 安全性

GET请求的参数会显示在URL中,因此对于敏感信息不宜使用GET请求,因为敏感信息可能会被浏览器保存、历史记录或被其他人看到。

POST请求的参数在请求的正文中,相对来说更加安全,但仍然不是绝对安全,因为HTTP是明文传输的,只有使用HTTPS才能加密传输数据。

4. 缓存与历史记录

GET请求会被浏览器主动缓存,而POST请求不会被缓存,除非手动设置。因为GET请求的参数附加在URL后面,浏览器会将URL作为缓存的标识。

5. 幂等性

GET请求是幂等的,多次执行相同的GET请求,服务器的状态不会发生变化。

POST请求不是幂等的,多次执行相同的POST请求可能会产生不同的结果,因为可能会导致服务器状态的变化。

三、GET和POST的使用场景

GET请求主要用于获取数据,因为它是幂等的、可缓存的。常见的使用场景包括:

  • 搜索引擎的搜索请求
  • 获取网页内容
  • 获取资源文件等

POST请求主要用于向服务器提交数据,因为它可能会导致状态变化或产生副作用。常见的使用场景包括:

  • 提交表单数据
  • 上传文件
  • 发表评论等

在实际应用中,要根据具体的需求选择GET或POST方法,合理地使用它们可以提升应用的性能和安全性。

四、示例代码

GET请求示例(JavaScript)

const url = "https://api.example.com/data?id=123";
fetch(url)
.then(response => response.json())
.then(data => {
console.log(data);
})
.catch(error => {
console.error("Error:", error);
});

POST请求示例(JavaScript)

const url = "https://api.example.com/submit";
const data = {
username: "user123",
password: "pass456"
};
fetch(url, {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(data)
})
.then(response => response.json())
.then(data => {
console.log(data);
})
.catch(error => {
console.error("Error:", error);
});

以上示例使用了fetch函数来发送GET和POST请求,通过Promise链式调用处理响应结果。

参考文献

说说 HTTP 常见的请求头有哪些? 作用?

一、什么是HTTP头字段?

HTTP头字段(HTTP header fields)是指在超文本传输协议(HTTP)的请求和响应消息中的消息头部分。它们定义了一个HTTP事务中的操作参数。HTTP头部字段可以根据需要自定义,因此可能在Web服务器和浏览器上发现非标准的头字段。

下面是一个HTTP请求的请求头示例:

GET /home.html HTTP/1.1
Host: developer.mozilla.org
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:50.0) Gecko/20100101 Firefox/50.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Referer: https://developer.mozilla.org/testpage.html
Connection: keep-alive
Upgrade-Insecure-Requests: 1
If-Modified-Since: Mon, 18 Jul 2016 02:36:04 GMT
If-None-Match: "c561c68d0ba92bbeb8b0fff2a9199f722e3a621a"
Cache-Control: max-age=0

二、常见的请求头字段

以下是一些常见的HTTP请求头字段及其说明:

1. Accept

用于指定能够接受的回应内容类型(Content-Types)。

2. Accept-Charset

用于指定能够接受的字符集。

3. Accept-Encoding

用于指定能够接受的编码方式列表,常见的有gzip、deflate等。

4. Accept-Language

用于指定能够接受的回应内容的自然语言列表,例如en-US表示英语(美国)。

5. Authorization

用于超文本传输协议的认证的认证信息,通常用于进行用户身份验证。

6. Cache-Control

用来指定在请求/响应链中的所有缓存机制都必须遵守的指令,例如no-cache表示不缓存。

用于服务器通过Set-Cookie发送的一个HTTP Cookie。

8. Content-Length

表示请求体的长度,以八位字节数组(8位的字节)表示。

9. Content-Type

用于指定请求体的多媒体类型,例如application/x-www-form-urlencoded表示表单数据。

10. User-Agent

表示浏览器的浏览器身份标识字符串,用于标识用户使用的浏览器信息。

11. Host

表示服务器的域名,以及服务器所监听的传输控制协议端口号。

12. Referer

表示请求的来源页面,即用户是从哪个页面跳转过来的。

13. Origin

用于发起一个针对跨来源资源共享的请求,表示允许跨域请求。

三、使用场景

通过配合请求头和响应头,可以实现一些常见的功能:

1. 协商缓存

通过请求头的If-Modified-SinceIf-None-Match和响应头的Last-ModifiedETag实现缓存的协商,减少不必要的数据传输。

2. 会话状态管理

通过请求头的Cookie字段,服务器可以在客户端维护会话状态,实现用户登录状态、购物车、个性化设置等功能。

以上是HTTP常见请求头及其作用的简要介绍,HTTP头字段在HTTP通信中扮演着重要的角色,帮助服务器和浏览器进行信息交换和功能实现。

参考文献

说说HTTP1.0/1.1/2.0的区别?

一、HTTP1.0

HTTP1.0是HTTP协议的第一个版本,也是第一个在通信中指定版本号的HTTP协议版本。

在HTTP1.0中,浏览器与服务器之间只保持短暂的连接,每次请求都需要与服务器建立一个TCP连接。服务器在完成请求处理后立即断开TCP连接,不保持与客户端的长连接,也不跟踪每个客户端的状态或记录过去的请求。

简单来说,每次与服务器交互都需要新开一个连接,如下图所示:

image

例如,在解析HTML文件时,如果文件中存在资源文件(如CSS、JS等),就需要创建单独的连接来获取这些资源,最终导致一个HTML文件的访问涉及多次请求和响应,每次请求都需要创建连接、建立连接和关闭连接,这种形式明显造成了性能上的缺陷。

如果需要建立长连接,需要设置一个非标准的Connection字段Connection: keep-alive

二、HTTP1.1

HTTP1.1在HTTP1.0的基础上进行了改进和优化。

在HTTP1.1中,默认支持长连接(Connection: keep-alive),即在一个TCP连接上可以传送多个HTTP请求和响应,减少了建立和关闭连接的消耗和延迟。

通过建立一次连接,多次请求可以由这个连接完成,如下图所示:

image

这样,在加载HTML文件的时候,文件中的多个请求和响应可以在一个连接中传输,提高了性能。

此外,HTTP1.1还引入了更多的请求头和响应头来完善功能,例如:

  • 引入了更多的缓存控制策略,如If-Unmodified-Since、If-Match、If-None-Match等缓存头来控制缓存策略。
  • 引入了range头,允许请求资源的某个部分。
  • 引入了host头,实现在一台WEB服务器上可以在同一个IP地址和端口号上使用不同的主机名来创建多个虚拟WEB站点。

同时,HTTP1.1还新增了其他的请求方法:PUT、DELETE、OPTIONS等。

三、HTTP2.0

HTTP2.0在相比之前版本,性能上有很大的提升,主要体现在以下几个方面:

1. 多路复用

HTTP2.0复用TCP连接,在一个连接上可以同时发送多个请求或回应,而且不需要按照顺序一一对应,避免了"队头堵塞"的问题。

通过复用连接,在同一个TCP连接里面,客户端可以同时发送多个请求,服务器也可以同时返回多个响应,这样大大减少了连接的建立和关闭次数,提高了并发性能,如下图所示:

image

2. 二进制分帧

HTTP2.0采用二进制格式传输数据,而非HTTP1.x的文本格式,解析起来更高效。

将请求和响应数据分割为更小的帧,并且它们采用二进制编码,这样数据传输更加紧凑高效。

HTTP2.0中,同域名下所有通信都在单个连接上完成,该连接可以承载任意数量的双向数据流。每个数据流都以消息的形式发送,而消息又由一个或多个帧组成。多个帧之间可以乱序发送,根据帧首部的流标识可以重新组装,这也是多路复用同时发送数据的实现条件。

3. 首部压缩

HTTP2.0使用首部表来跟踪和存储之前发送的键值对,对于相同的数据,不再通过每次请求和响应发送。

首部表在HTTP2.0的连接存续期内始终存在,由客户端和服务器共同渐进地更新。这样就实现了对HTTP1.x中冗余头部信息的压缩,减少了数据传输量,降低了开销。

例如,下图中的两个请求,请求一发送了所有的头部字段,第二个请求则只需要发送差异数据,这样可以减少冗余数据,降低开销。

image

4. 服务器推送

HTTP2.0引入了服务器推送,允许服务器将一些客户端需要的资源预先推送到客户端。

服务器可以顺便把一些客户端需要的资源一起推送到客户端,如在响应一个页面请求时,可以随同页面的其他资源一起推送。这样免得客户端再次创建连接发送请求到服务器端获取资源,提高了性能。

服务器推送适合用于加载静态资源,如图片、CSS、JS等,如下图所示:

image

四、总结

HTTP1.0、HTTP1.1和HTTP2.0在性能和功能方面都有很大的区别。

HTTP1.0通过短连接来实现请求和响应,HTTP1.1引

入了长连接和更多的请求头和响应头来优化。

而HTTP2.0则进一步提升了性能,通过多路复用、二进制分帧、首部压缩和服务器推送等特性来优化数据传输和性能表现。

随着HTTP2.0的逐渐普及,网络通信将更加高效快速,为用户提供更好的上网体验。

参考文献

说说HTTP 常见的状态码有哪些,适用场景?

一、HTTP状态码

HTTP状态码(HTTP Status Code)是用来表示网页服务器超文本传输协议响应状态的3位数字代码。它由RFC 2616规范定义,并得到RFC 2518、RFC 2817、RFC 2295、RFC 2774与RFC 4918等规范扩展。简单来说,HTTP状态码是服务器告诉客户端当前请求响应的状态,通过状态码可以判断和分析服务器的运行状态。

二、常见状态码

HTTP状态码分为五类,每类以不同的数字开头表示不同的响应状态:

1xx - 信息类

1xx状态码表示请求已被接受,需要继续处理。这类响应是临时响应,只包含状态行和某些可选的响应头信息,并以空行结束。常见状态码有:

  • 100(继续):客户端继续发送请求,这是临时响应,用来通知客户端部分请求已经被服务器接收,且仍未被拒绝。客户端应当继续发送请求的剩余部分,或者如果请求已经完成,忽略这个响应。服务器必须在请求完成后向客户端发送一个最终响应。
  • 101(切换协议):服务器根据客户端的请求切换协议,主要用于WebSocket或HTTP/2升级。

2xx - 成功类

2xx状态码表示请求已成功被服务器接收、理解,并接受。常见状态码有:

  • 200(成功):请求已成功,请求所希望的响应头或数据体将随此响应返回。
  • 201(已创建):请求成功并且服务器创建了新的资源。
  • 204(无内容):服务器成功处理请求,但没有返回任何内容。

3xx - 重定向类

3xx状态码表示要完成请求,需要进一步操作。通常,这些状态代码用来重定向。常见状态码有:

  • 301(永久重定向):请求的网页已永久移动到新位置。服务器返回此响应时,会自动将请求者转到新位置。
  • 302(临时重定向):服务器目前从不同位置的网页响应请求,但请求者应继续使用原有位置来进行以后的请求。
  • 304(未修改):服务器告诉客户端可以直接使用缓存的版本,无需重新请求。
  • 307(临时重定向):服务器目前从不同位置的网页响应请求,但请求者应继续使用原有位置来进行以后的请求。

4xx - 客户端错误类

4xx状态码代表了客户端看起来可能发生了错误,妨碍了服务器的处理。常见状态码有:

  • 400(错误请求):服务器不理解请求的语法。
  • 401(未授权):请求要求身份验证。对于需要登录的网页,服务器可能返回此响应。
  • 403(禁止):服务器拒绝请求。
  • 404(未找到):服务器找不到请求的网页。

5xx - 服务器错误类

5xx状态码表示服务器无法完成明显有效的请求。这类状态码代表了服务器在处理请求的过程中有错误或者异常状态发生。常见状态码有:

  • 500(服务器内部错误):服务器遇到错误,无法完成请求。
  • 502(错误网关):服务器作为网关或代理,从上游服务器收到无效响应。
  • 503(服务不可用):服务器目前无法使用(由于超载或停机维护)。

三、适用场景

不同的状态码适用于不同的场景,下面给出一些常见的适用场景:

  • 200:表示请求成功,服务器正确处理了请求。
  • 204:表示服务器正确处理了请求,但没有返回任何内容,通常用于删除操作等。
  • 301:表示永久重定向,请求的资源已经被永久移动到新的位置。
  • 400:表示客户端请求错误,服务器无法理解请求的语法。
  • 403:表示请求被服务器拒绝,没有权限访问该资源。
  • 404:表示请求的资源不存在,服务器找不到请求的网页。

不同的状态码对应不同的请求处理情况,客户端可以根据状态码来判断请求是否成功,并做相应处理。

参考文献

说说TCP为什么需要三次握手和四次挥手?

一、TCP三次握手

TCP三次握手是在建立TCP连接时需要进行的过程,用于确认双方的接收能力和发送能力是否正常,以及指定序列号等参数。

握手过程:

  1. 第一次握手:客户端发送一个SYN包,指定自己的初始序列号ISN(c),此时客户端处于SYN_SENT状态。
  2. 第二次握手:服务端收到客户端的SYN包后,以自己的SYN包作为应答,确认客户端的SYN,并将客户端的ISN+1作为ACK的值,此时服务端处于SYN_RCVD状态。
  3. 第三次握手:客户端收到服务端的SYN包后,发送一个ACK包,值为服务端的ISN+1。此时客户端处于ESTABLISHED状态,服务端也处于ESTABLISHED状态,双方连接建立完成。

通过三次握手,双方确认了彼此的接收和发送能力正常,可以进行正常的数据传输。

为什么需要三次握手?

如果只有两次握手,发送端可以确认自己发送的信息对方能收到,也可以确认对方发送的信息自己能收到,但接收端无法确认自己发送的信息对方是否能收到。因此,需要三次握手来确认双方的接收和发送能力都正常。

另外,三次握手可以防止已失效的连接请求报文段再次传到服务端,导致服务器资源浪费。

二、TCP四次挥手

TCP四次挥手是在断开TCP连接时需要进行的过程,用于正常关闭连接。

挥手过程:

  1. 第一次挥手:客户端发送一个FIN包,指定一个序列号。此时客户端处于FIN_WAIT1状态,停止发送数据,等待服务端的确认。
  2. 第二次挥手:服务端收到FIN包后,发送一个ACK包,且将客户端的序列号值+1作为ACK包的序列号值,表明已经收到客户端的FIN包。此时服务端处于CLOSE_WAIT状态。
  3. 第三次挥手:如果服务端也想断开连接,服务端发送一个FIN包,指定一个序列号。此时服务端处于LAST_ACK状态。
  4. 第四次挥手:客户端收到服务端的FIN包后,发送一个ACK包作为应答,且将服务端的序列号值+1作为ACK包的序列号值,此时客户端处于TIME_WAIT状态。需要等待一段时间以确保服务端收到自己的ACK包之后才会进入CLOSED状态,服务端收到ACK包后,就处于关闭连接了,处于CLOSED状态。

四次挥手原因

服务端在收到客户端断开连接FIN包后,并不会立即关闭连接,而是先发送一个ACK包先告诉客户端收到关闭连接的请求,只有当服务器的所有报文发送完毕之后,才发送FIN包断开连接,因此需要四次挥手。

三、总结

TCP三次握手和四次挥手是TCP连接建立和断开过程中必要的步骤,通过这些步骤,可以保证连接的可靠性和正常关闭,确保数据的准确传输和释放服务器资源。

参考文献

说说地址栏输入 URL 敲下回车后发生了什么?

image

一、URL解析和DNS查询

当你在浏览器的地址栏中输入一个URL并敲下回车时,浏览器会首先对URL进行解析。URL通常由多个部分组成,包括协议(例如http或https)、域名或IP地址、端口号(如果未指定则使用默认端口)、路径和查询参数等。

浏览器解析URL后,会提取出其中的域名部分,然后进行DNS查询以将域名转换为对应的IP地址。DNS查询是将域名映射到IP地址的过程,浏览器向本地DNS服务器发送查询请求,本地DNS服务器会向根DNS服务器逐级查询,直到找到目标域名对应的IP地址。一旦得到IP地址,浏览器就可以向服务器发送请求。

二、TCP连接和HTTP请求

接下来,浏览器需要与目标服务器建立TCP连接。TCP连接是一种面向连接的传输协议,确保数据的可靠传输。在建立TCP连接时,浏览器会经历一个三次握手的过程,确保客户端和服务器之间的连接状态正常。

当TCP连接建立后,浏览器会发送HTTP请求到服务器。HTTP请求包括请求行、请求头和请求体。请求行包含请求方法(例如GET、POST等)和路径信息。请求头包含一些额外的信息,例如浏览器的User-Agent、Accept-Encoding等。请求体包含一些提交的数据,例如表单数据或JSON数据等。

三、服务器处理和HTTP响应

服务器收到HTTP请求后,会根据请求的内容进行处理。服务器可能会读取请求体中的数据,查询数据库,执行业务逻辑等操作。

处理完成后,服务器会生成HTTP响应并发送回浏览器。HTTP响应包括状态行、响应头和响应体。状态行包含状态码,表示服务器处理请求的结果。响应头包含一些附加信息,例如服务器类型、响应时间等。响应体包含实际返回的数据,例如HTML页面、JSON数据等。

image

四、页面渲染

image

浏览器收到服务器的响应后,会对返回的资源进行解析和渲染。如果响应是HTML页面,浏览器会构建DOM树和CSS规则树,并最终生成渲染树。然后浏览器会对渲染树进行布局和绘制,最终将页面呈现给用户。

在页面渲染的过程中,浏览器还会下载页面中引用的其他资源,例如CSS文件、JavaScript文件、图片等,并对这些资源进行相同的解析和渲染过程。

1. 解析HTML

浏览器从服务器接收到HTML文档后,会进行解析,构建DOM树(文档对象模型)。DOM树是文档的逻辑结构表示,每个HTML标签都会被解析成DOM树的一个节点,标签之间的嵌套关系则对应着DOM树中的父子关系。

2. 解析CSS

解析CSS样式表,生成CSS规则树(样式表对象模型)。CSS规则树描述了文档中各个元素应用的样式信息。DOM树和CSS规则树结合后形成渲染树(Render Tree),渲染树只包含需要显示的节点和其对应的样式信息。

3. 布局(Layout)

渲染树中的每个节点都有对应的几何信息,例如位置、大小等。布局阶段会根据渲染树中每个节点的几何信息计算节点在页面中的精确位置,确定每个元素在屏幕上的显示位置。

4. 绘制(Paint)

在布局完成后,浏览器将根据渲染树和布局阶段得到的几何信息来绘制页面。这个过程将把页面的每个节点转换为屏幕上的实际像素,创建一个包含所有像素信息的位图。

5. 合成(Composite)

绘制阶段完成后,浏览器会将各个图层(Layer)按照合成顺序进行合并,形成最终的页面图像。合成是将各个图层的像素信息进行组合,以最终形成用户所见的页面。

值得注意的是,现代浏览器为了提高性能和用户体验,会采用一些优化技术,例如异步加载脚本、懒加载图片、预渲染等。这些优化技术可以减少页面加载时间和渲染时间,提高页面的显示速度和响应性。

页面渲染是整个过程中较为复杂的一部分,它涉及到浏览器的多个模块协同工作,确保用户能够快速、流畅地浏览网页内容。

五、总结

整个过程可以总结为:

  1. URL解析和DNS查询,将域名解析为IP地址;
  2. 建立TCP连接,确保数据传输的可靠性;
  3. 发送HTTP请求,向服务器请求资源;
  4. 服务器处理请求并发送HTTP响应;
  5. 浏览器解析和渲染页面,显示给用户。

这些步骤使得用户可以通过浏览器访问互联网上的各种资源,从而实现网页浏览、数据传输等功能。

参考文献

说说对WebSocket的理解?应用场景?

一、WebSocket 是什么?

WebSocket 是一种网络传输协议,位于 OSI 模型的应用层。它允许在单个 TCP 连接上进行全双工通信,实现了客户端与服务器之间的双向数据传输,从而能更好地节省服务器资源和带宽,并达到实时通信的效果。

在传统的 HTTP 协议中,客户端需要不断发送请求以获取服务器的响应数据,这种轮询的方式对服务器和网络资源产生较大的负担。而 WebSocket 的出现改变了这种情况,通过一次握手连接,客户端和服务器之间可以创建持久性的连接,随时进行双向数据交换,大大降低了通信的延迟和资源消耗。

二、WebSocket 的特点

1. 全双工通信

WebSocket 支持全双工通信,允许数据在两个方向上同时传输,客户端和服务器可以实时地发送和接收数据,达到瞬时同步的效果。

2. 二进制帧结构

WebSocket 采用二进制帧结构,与 HTTP 完全不兼容。相比起 HTTP/2,WebSocket 更侧重于实时通信,不像 HTTP/2 那样定义流和多路复用等特性,因为 WebSocket 自身已经是全双工通信,不需要这些特性。

3. 协议名和握手

WebSocket 引入了 ws 和 wss 分别代表明文和密文的 WebSocket 协议,且默认端口使用 80 或 443,与 HTTP 的端口一致。在连接建立时,客户端需要发送协议升级请求并进行握手,服务端返回接受握手请求的响应,完成连接的建立。

4. 优点

  • 较少的控制开销:相对于 HTTP 每次请求都需要携带完整的头部,WebSocket 的数据包头部较小,减少了控制开销。
  • 更强的实时性:相对于 HTTP 请求需要等待客户端发起请求才能响应,WebSocket 实现了持久连接,实时性更好。
  • 保持连接状态:WebSocket 连接建立后,客户端和服务器之间可以保持连接状态,省去了每次请求都要携带身份验证的过程。
  • 更好的二进制支持:WebSocket 定义了二进制帧,更好地处理二进制内容。
  • 支持扩展:用户可以扩展 WebSocket 协议,实现自定义的子协议,增加了灵活性。
  • 更好的压缩效果:在适当的扩展支持下,WebSocket 可以沿用之前内容的上下文,在传递类似的数据时,可以显著提高压缩率。

三、应用场景

WebSocket 的实时通信特性使得它在许多场景下得到广泛应用:

  • 弹幕:在直播或视频网站中,用户可以实时发送弹幕评论,通过 WebSocket 实时将弹幕内容显示在视频画面上。
  • 媒体聊天:实现在线即时通信功能,例如在线聊天室、即时消息应用等。
  • 协同编辑:多个用户可以同时编辑同一个文档,实现实时协作编辑。
  • 基于位置的应用:例如地图应用中,实时显示用户的位置信息。
  • 体育实况更新:在体育比赛进行时,实时更新比分和比赛进展。
  • 股票基金报价实时更新:股票和基金价格实时更新,及时推送最新的行情信息。

总的来说,WebSocket 在需要实时通信和即时更新数据的场景下都能发挥出很大的作用,提升用户体验,减少服务器压力,逐渐成为现代 Web 应用中不可或缺的技术之一。

使用

当使用 WebSocket 进行通信时,通常需要在客户端和服务器端分别实现 WebSocket 的功能。下面我将给出一个简单的示例,展示如何使用 JavaScript 在客户端建立 WebSocket 连接并发送和接收消息,以及如何在 Python 中创建一个简单的 WebSocket 服务器。

在客户端使用 WebSocket

<!DOCTYPE html>
<html>
<head>
<title>WebSocket Client</title>
</head>
<body>
<input type="text" id="messageInput" placeholder="Enter your message">
<button onclick="sendMessage()">Send</button>
<div id="messageArea"></div>

<script>
const socket = new WebSocket("ws://your_server_address");

socket.onopen = function() {
showMessage("WebSocket connection established.");
};

socket.onmessage = function(event) {
showMessage("Received: " + event.data);
};

function sendMessage() {
const messageInput = document.getElementById("messageInput");
const message = messageInput.value;
socket.send(message);
showMessage("Sent: " + message);
messageInput.value = "";
}

function showMessage(message) {
const messageArea = document.getElementById("messageArea");
messageArea.innerHTML += "<p>" + message + "</p>";
}
</script>
</body>
</html>

在上面的示例中,首先我们创建了一个 WebSocket 对象,传入服务器地址 ws://your_server_address。然后,我们监听 WebSocket 的 onopen 事件,当连接建立时会显示连接已经建立。监听 onmessage 事件,当接收到消息时会在页面上显示收到的消息。通过输入框和按钮可以向服务器发送消息,点击按钮时调用 sendMessage() 函数将输入框中的消息发送给服务器,并将消息显示在页面上。

在服务器端使用 WebSocket

在 Node.js 中,你可以使用 ws 模块来创建 WebSocket 服务器。这个模块提供了 WebSocket 的实现,使你能够轻松地创建一个 WebSocket 服务器,并与客户端进行实时通信。

下面是使用 Node.js 创建 WebSocket 服务器的代码示例:

首先,确保你已经安装了 ws 模块:

npm install ws

然后,创建一个 Node.js 文件 websocket_server.js,包含以下代码:

const WebSocket = require('ws');

const wss = new WebSocket.Server({ port: 8080 });

wss.on('connection', (ws) => {
console.log('Client connected');

ws.on('message', (message) => {
console.log('Received: ' + message);
// 在这里你可以对接收到的消息进行处理
// 例如,将消息广播给所有连接的客户端
wss.clients.forEach((client) => {
if (client !== ws && client.readyState === WebSocket.OPEN) {
client.send('Broadcast: ' + message);
}
});
});

ws.on('close', () => {
console.log('Client disconnected');
});
});

console.log('WebSocket server started at ws://localhost:8080');

在上面的代码中,我们使用 ws 模块创建了一个 WebSocket 服务器,监听在本地地址 ws://localhost:8080 上。当有客户端连接到服务器时,connection 事件会被触发,并创建一个 WebSocket 实例 ws。然后,我们监听 message 事件,当客户端发送消息时会收到该事件,并在控制台上显示接收到的消息。在这个示例中,我们将收到的消息广播给所有连接的客户端,除了发送消息的客户端本身。

运行 WebSocket 服务器:

node websocket_server.js

现在,服务器已经在本地地址 ws://localhost:8080 上运行,客户端可以连接到该地址,并与服务器进行实时通信。

参考文献