网络模型 - TCP/IP网络模型,链路层,网络层,传输层,应用层
2026-01-12 11:25:37 21 举报
AI智能生成
计算机网络,数据传输,网络模型。基于OSI网络模型,重点包括tcp/ip协议。其中知识图谱涵盖: HTTP, FTP,SSH, TELNET, SIP, DHCP,Stream编程,WebSokect编程 TCP/UDP 协议 IP,IPV4,IPV6 协议;
作者其他创作
大纲/内容
网络模型
<b>网络有 3 种分层模型:</b>
<b>协议</b>
<b>设备</b>
<b>每层对主要用途:</b><br>
TCP/IP 网络 4 层模型
应用层
最上层的是我们能直接接触到是<font color="#f44336">应用层(Application Layer)</font>,电脑/手机提供访问网络服务的接口。数据传输基本单位为报文;<br>
应用层只需要专注于<b>为用户提供应用功能</b>
比如 HTTP、FTP、Telnet、DNS、DHCP、SMTP等。
再如 SIP协议,WebSocket协议
HTTP(HyperText Transfer Protocol:超文本传输协议)【TCP,端口80】是可靠的数据传输协议。浏览器向服务器发收报文前,先建立TCP连接。<br>HTTPS(Secure)是安全的HTTP协议,【端口443】。基于HTTP协议,通过SSL或TLS提供加密处理数据、验证对方身份以及数据完整性保护。
HTTP的工作原理如下:<br>客户端发送一个HTTP请求到服务器,请求中包含了要访问的资源的URL、请求方法(如GET、POST等)、请求头部等信息。<br>服务器接收到请求后,根据请求的URL和方法,处理请求并返回相应的HTTP响应。<br>响应中包含了状态码、响应头部和响应体等信息。状态码表示请求的处理结果,如200表示成功,404表示资源未找到等。<br>客户端接收到响应后,根据响应的内容进行处理,如渲染页面、下载文件等。
FTP(File Transfer Protocol,文件传输协议)【TCP,端口21】是一种用于在网络上进行文件传输的协议。它是一个客户端-服务器协议<br>
FTP的工作原理如下:<br>建立连接:客户端通过TCP/IP协议与服务器建立连接。默认情况下,FTP使用端口号21进行控制连接,用于发送命令和接收响应。<br>身份验证:客户端在连接建立后,需要提供用户名和密码进行身份验证。一旦验证成功,客户端就可以执行文件传输操作。<br>控制连接:控制连接用于发送命令和接收响应。客户端通过发送命令告知服务器要执行的操作,服务器则返回相应的响应码和响应消息。<br>数据连接:在进行文件传输时,客户端和服务器之间需要建立数据连接。数据连接可以是主动模式或被动模式。<br>文件传输:基于2种连接,客户端可以使用命令进行文件传输操作,如上传、下载、删除和重命名文件等。客户端发送相应的命令,服务器执行相应的操作,并返回相应的响应码和响应消息。<br>断开连接:当文件传输完成或不再需要连接时,客户端可以发送QUIT命令来断开与服务器的连接。<br>
FTP在需要大量文件传输的场景下。应用场景:<br>网站维护:网站管理员可以使用FTP将网站文件上传到服务器,以更新网站内容。<br>文件共享:FTP可以用于在不同计算机之间共享文件,用户可以通过FTP客户端从服务器上下载文件。<br>备份和恢复:FTP可以用于将重要文件备份到远程服务器,以防止数据丢失。在需要时,可以使用FTP将备份文件恢复到本地计算机。<br>软件更新:软件开发人员可以使用FTP将软件更新文件上传到服务器,以便用户可以下载并安装最新版本的软件。<br>大文件传输:由于FTP支持断点续传,因此可以用于传输大文件,即使在网络连接中断后也可以从中断处继续传输。
Telnet是一种用于远程登录和管理计算机网络设备的协议。它允许用户通过网络连接到远程主机,并在远程主机上执行命令和操作。<br>Telnet协议基于客户端-服务器模型,其中客户端是用户的计算机,而服务器是远程主机。<br>
Telnet的工作原理如下:<br>客户端发起连接:用户在本地计算机上运行Telnet客户端程序,并指定要连接的远程主机的IP地址或域名。<br>建立连接:Telnet客户端使用TCP/IP协议与远程主机建立连接。这通常是通过Telnet默认端口23进行的。<br>用户认证:一旦连接建立,远程主机会要求用户进行身份验证。用户需要提供正确的用户名和密码才能登录到远程主机。<br>远程会话:一旦用户通过身份验证,Telnet客户端和远程主机之间建立了一个双向的虚拟终端会话。用户可以在本地计算机上输入命令,并将其发送到远程主机执行。远程主机将执行结果发送回Telnet客户端,然后显示在用户的本地终端上。<br>断开连接:当用户完成操作后,可以选择断开Telnet连接。Telnet客户端发送一个断开连接的请求给远程主机,然后关闭本地连接。<br>
Telnet的应用包括:<br>远程登录:Telnet最常用的应用是远程登录到远程主机,以便在远程主机上执行命令和操作。可以通过Telnet远程管理和维护多台计算机。<br>网络设备管理:Telnet也广泛用于管理网络设备,如路由器、交换机和防火墙。通过Telnet,可以远程配置和监控这些设备,而无需直接物理接触设备。<br>远程协作:Telnet还可以用于远程协作和共享文件。多个用户可以同时连接到远程主机,并在同一个会话中共享文件和资源。
DNS(Domain Name System:域名系统)【TCP和UDP】解决IP地址难以记忆的问题,存储并完成自己所管辖范围内主机的 <b>域名 到 IP </b>地址的映射
DNS原理:<br>域名解析:当用户在浏览器中输入一个域名时,浏览器会向本地DNS服务器发送一个域名解析请求。本地DNS服务器会首先查询自己的缓存,如果有对应的IP地址,则直接返回给浏览器;如果没有,则向根域名服务器发送请求。<br>递归查询:根域名服务器收到请求后,会返回给本地DNS服务器一个所查询域名的顶级域名服务器的IP地址。本地DNS服务器再向顶级域名服务器发送请求,顶级域名服务器返回给本地DNS服务器该域名的下一级域名服务器的IP地址。这个过程会一直递归下去。<br>缓存:本地DNS服务器会将查询过的域名和对应的IP地址缓存起来,以便下次查询时可以直接返回结果,提高查询效率。<br>
域名解析的顺序:<br>【1】浏览器缓存,<br>【2】找本机的hosts文件,<br>【3】路由缓存,<br>【4】找DNS服务器(本地域名、顶级域名、根域名)->迭代解析、递归查询。
应用:<br>域名解析:DNS最常见的应用就是将域名解析为IP地址,这样用户只需要记住易于记忆的域名,而不需要记住复杂的IP地址。<br>负载均衡:DNS还可以用于实现负载均衡。当一个域名对应多个IP地址时,DNS服务器可以根据不同的策略将请求分发到不同的服务器上。<br>邮件传输:当发送邮件时,邮件服务器会通过DNS查找目标邮件服务器的IP地址将邮件传递给正确的服务器。<br>安全性:DNS也可以用于实现安全性控制,如防火墙和内容过滤。通过DNS可以将恶意域名或不安全的网站进行屏蔽。
DHCP(Dynamic Configuration Protocol:动态主机设置协议)【UDP】 是一个局域网协议,为临时接入局域网的用户自动分配IP地址。<br>
SIP (Session Initiation Protocol)是一个应用层的信令控制协议。用于创建、修改和释放一个或多个参与者的会话。
SIP作为应用层协议,在传输层上可以使用TCP,也可以使用UDP。SIP可以支持IPv4和IPv6。
会话可以是IP电话,号码解析,多媒体分发,多媒体会议
SIP协议采用Client/Server模型,主要通过与Proxy Server之间的通信来完成用户呼叫的建立过程。<br>
传输层
应用层的数据包会传给<font color="#f44336">传输层(Transport Layer)</font>。<b>传输层的报文中会携带端口号</b>,因此<b>接收方可以识别出该报文是发送给哪个应用</b>。
在传输层会有两个传输协议,分别是 TCP 和 UDP。
TCP 的全称叫传输控制协议(Transmission Control Protocol),大部分应用使用的正是 TCP 传输层协议,比如 HTTP 应用层协议。<br>TCP 相比 UDP 多了很多特性,比如流量控制、超时重传、拥塞控制等,这些都是为了保证数据包能可靠地传输给对方。
对应用层报文进行分段和重组;<br>面向应用层实现复用与分解;<br>实现端到端的流量控制;拥塞控制;<br>对收到的报文进行差错检测(首部和数据部分都检错);<br>实现进程间的端到端可靠数据传输控制。
建立连接(三次握手)<br>
释放连接(四次挥手)<br>
UDP 相对来说就很简单,简单到只负责发送数据包,不保证数据包是否能抵达对方,但它实时性相对更好,传输效率也高。<br>UDP 也可以实现可靠传输,把 TCP 的特性在应用层上实现就可以,不过要实现一个商用的可靠 UDP 传输协议,也不是一件简单的事情。
UDP是无连接协议;<br>UDP不能保证可靠的交付数据;<br>UDP是面向报文传输的;<br>UDP没有拥塞控制;<br>UDP首部开销很小。
应用需要传输的数据可能会非常大,如果直接传输就不好控制,因此当传输层的数据包大小超过 MSS(TCP 最大报文段长度) ,<br>就要将数据包分块,这样即使中途有一个分块丢失或损坏了,只需要重新发送这一个分块,而不用重新发送整个数据包。<br>在 TCP 协议中,我们把每个分块称为一个 <font color="#ff0000">TCP 段</font>(TCP Segment)。<br>
当设备作为接收方时,传输层则要负责把数据包传给应用,但是一台设备上可能会有很多应用在接收或者传输数据,因此需要用一个编号将应用区分开来,这个编号就是<font color="#ff0000">端口</font>。比如 80 端口通常是 Web 服务器用的,22 端口通常是远程登录服务器用的。而对于浏览器(客户端)中的每个标签栏都是一个独立的进程,操作系统会为这些进程分配临时的端口号。
网络层
实际的IP报文传输功能是交给 <font color="#ff0000">网络层</font>(Internet Layer)。<br>
<br>
网络层最常使用的是 IP 协议(Internet Protocol),<b>IP 协议会将传输层的报文作为数据部分,再加上 IP 包头组装成 IP 报文</b>,<br>如果 IP 报文大小超过 MTU(以太网中一般为 1500 字节)就会 再次进行分片,得到一个即将发送到网络的 IP 报文。
网络层负责将数据从一个设备传输到另一个设备,世界上那么多设备,又该如何找到对方呢?因此,网络层需要有区分设备的编号。
IPV4 地址
一般用 IP 地址给设备进行编号,对于 IPv4 协议, IP 地址共 32 位bit,分成了四段(比如,192.168.100.1),每段是 8 位bit。<br>只有一个单纯的 IP 地址虽然做到了区分设备,但是寻址起来就特别麻烦,全世界那么多台设备,所以ip划分了两个意义:
因此,需要将 IP 地址分成两种意义:<br><ul><li>一个是网络号,负责标识该 IP 地址是属于哪个「子网」的;</li><li>一个是主机号,负责标识同一「子网」下的不同主机;</li></ul>
配合 <b>子网掩码 </b>才能算出 IP 地址 的网络号和主机号。<br>比如 10.100.122.0/24,后面的 /24简化子网掩码 表示就是 255.255.255.0 的子网掩码。<br>255.255.255.0 二进制是「11111111-11111111-11111111-00000000」,共有 24 个1。
知道了子网掩码,该怎么计算出网络地址和主机地址呢?<br>将 10.100.122.2 和 255.255.255.0 进行<b>按位与运算</b>,就可以得到网络号。<br>那么在寻址的过程中,先匹配到相同的网络号(表示要找到同一个子网),才会去找对应的主机。<br><b>网络地址:10.100.122.0,广播地址:10.100.122.255,主机地址10.100.122.1-10.100.122.254</b>
<br>
A类(8网络号+24主机号)、B类(16网络号+16主机号)、C类(24网络号+8主机号)可以用于标识网络中的主机或路由器,<br>D类地址作为组广播地址,E类是地址保留。<br>
IPV6地址
<font color="#494949">IPv6地址长度为128位,表示为8个段"X:X:X:X:X:X:X:X", 每个X代表4个十六进制值字符,以冒号分隔,一共被分为8组。</font>
<font color="#494949">FC00:0000:130F:0000:0000:09C0:876A:130B,<br>还可以写为缩略形式:每组中的前导“0”都可以省略,可写为:FC00:0:130F:0:0:9C0:876A:130B。<br>如果地址中包含连续两个或多个均为0的组,可以用双冒号“::”来代替,进一步简写为:FC00:0:130F::9C0:876A:130B。</font><br>
IPV6的优势
增加了大量的可用地址<br>增加了网络传输层的安全性<br>IPv6对网络性能的影响比较小<br>
IPV6地址<font color="#0d0b22">如何使用</font>
1.操作系统必须与IPv6兼容。Windows Vista和Windows的较新版本,Mac OS X的现代版本以及Linux。<br>2.路由器支持IPv6。如果您想尝试使用IPv6,请检查路由器的详细信息。<br>3. Internet服务提供商(ISP)也必须支持IPv6。即使您具有合适的操作系统和路由器,您的ISP也必须提供IPv6连接。
NAT 网络地址转换
从内网出去的IP数据报,将其IP地址替换为NAT服务器拥有的合法的公共IP地址,并将替换关系记录到NAT转换表中;<br>
从公共互联网返回的IP数据报,依据其目的的IP地址检索NAT转换表,并利用检索到的内部私有IP地址替换目的IP地址,将IP数据报转发到内部网络。
ARP 地址解析协议
ARP(Address Resolution Protocol)地址解析协议为网卡(网络适配器)的IP地址到对应的硬件地址提供动态映射。可以把网络层32位地址转化为数据链路层MAC48位地址。ARP 是即插即用的,一个ARP表是自动建立的,不需要系统管理员来配置。<br>
RARP(Reverse Address Resolution Protocol)协议指逆地址解析协议,可以把数据链路层MAC48位地址转化为网络层32位地址。
ICMP(Internet Control Message Protocol)
<b>这是一个 网络层 协议。ICMP 主要用于诊断和报告网络通信中的问题。</b>
ping 是基于 ICMP 协议,直接工作在 网络层,不涉及端口号。<br>
ICMP 不使用端口号。它是基于 IP 协议工作的,不属于传输层(不像 TCP 或 UDP 那样使用端口号)。ICMP 的报文包括 类型 和 代码 字段,最常见的是类型 8(Echo Request)和类型 0(Echo Reply)。
除了寻址能力, IP 协议还有另一个重要的能力就是 <b>路由</b>。实际场景中,两台设备并不是用一条网线连接起来的,而是通过很多网关、路由器、交换机<br>等众多网络设备连接起来的,那么就会形成很多条网络的路径,因此当数据包到达一个网络节点,就需要通过路由算法决定下一步走哪条路径。<br>路由器寻址工作中,就是要通过<b>网络号</b>找到目标地址的<b>子网</b>,找到后进而把数据包转发给对应的网络内。<br>
所以,<b>IP 协议的寻址作用是告诉我们去往下一个目的地该朝哪个方向走,路由则是根据「下一个目的地」选择路径。<br>寻址更像在导航,路由更像在操作方向盘。</b>
数据链路层
数据链路层
该层的作用包括:物理地址寻址、数据的成帧、流量控制、数据的检错、重发。基本数据单位为帧;<br>主要的协议:以太网协议;<br>两个重要设备名称:网桥和交换机。
什么是以太网?电脑上的以太网接口,Wi-Fi接口,以太网交换机、路由器上的千兆,万兆以太网口,还有网线,<br>它们都是以太网的组成部分。以太网就是一种在「局域网」内,把附近的设备连接起来,使它们之间可以进行通讯的技术。
以太网在判断网络包目的地时和 IP 的方式不同,因此必须采用相匹配的方式才能在以太网中将包发往目的地,<br>而 MAC 头部就是干这个用的,所以,在以太网进行通讯要用到 MAC 地址。
MAC 头部是以太网使用的头部,它包含了接收方和发送方的 MAC 地址等信息,<br>我们可以通过 ARP 协议获取对方的 MAC 地址。
所以说,网络接口层主要为网络层提供「链路级别」传输的服务,负责在以太网、WiFi 这样的底层网络上发送原始数据包,<br>工作在网卡这个层次,使用 MAC 地址来标识网络上的设备。
以太网帧结构<br>
类型:标识上层协议(2字节)<br>目的地址和源地址:MAC地址(每个6字节)<br>数据:封装的上层协议的分组(46~1500字节)<br>CRC:循环冗余码(4字节)<br>
MAC 物理地址<br>
MAC地址长度为6字节,48位;<br>MAC地址具有唯一性,每个网络适配器对应一个MAC地址;<br>通常采用十六进制表示法,每个字节表示一个十六进制数,用 - 或 : 连接起来;<br>MAC广播地址:FF-FF-FF-FF-FF-FF。
总结
每一层的封装格式:
网络分类<br>
按分布范围分类:
公网
<br>公网是指可以公开访问、由多个用户共享的网络。公网的一个典型例子就是互联网,它是全球范围内最广泛的公共网络。<br>
公网的特点:<br>
开放性: 公网通常是开放的,任何符合标准的设备和用户都可以访问。<br>IP地址可路由: 公网使用的IP地址是可以在互联网上路由的,即这些地址是全球唯一且公开的,能够与其他设备直接通信。<br>访问控制: 公网通过路由器、网络安全设备(如防火墙)和通信协议来进行流量管理和安全控制。<br>
公网地址的规律
<br>
广域网
几十到几千千米
广域网(WAN)是指覆盖范围较大的网络,通常跨越城市、国家甚至全球。广域网连接了多个局域网(LAN),使得不同地点的计算机和设备能够进行远距离通信。广域网通常使用公共通信基础设施(如电信公司提供的线路、互联网等)来传输数据。<br>
广域网的特点:<br>
覆盖范围大: 广域网连接了多个地理位置分散的局域网。<br>使用公共设施: 传输介质可能是公用的网络,如互联网、专用线路、卫星通信等。<br>传输技术多样: 包括IP网络、MPLS、VPN、帧中继、光纤链路等。<br>
广域网中的常见应用:<br>
连接公司总部与远程分支机构。<br>企业分布式办公室通过广域网。<br>支持远程工作和云服务访问。
城域网
整个城市
局域网
几十米到几千米
<br>
个人区域网
直径约10m(路由器)
按传输技术分类:
广播式网络:
所有计算机共享一个公共通信信道
eg:电视台发送一个信号,所有电视接收信号播放广播
点对点网络:
每条物理线路连接一对计算机(家庭中的网线连接计算机)
按拓扑结构分类
总线型网络
星型网络
环形网络
网状线网络
按交换技术分类:
电路减缓网络
在发送、接收双方建立一条专用通路用于数据传输
报文交换网络
将数据加上地址,进行转发,每个报文自行选择路线
分组交换网络
在报文基础上,将数据分成小数据块,类似报文交换
网络性能指标
时延
发送时延
传播时延
处理时延
排队时延
往返时延
从发送端发送数据到接收端的确认总经历时长
吞吐量<br>
单位时间通过接口的数据量
速率
单位时间通过主机的数据量
比如一个主机连接了3个接口,一个接口的速率是10KB/S ,那么这个主机的速率则是30ks的吞吐量
带宽,最高数据率成为带宽
SIP协议
基本功能
确定用户位置:确定被叫SIP终端所在的位置。SIP的最强大之处就是用户定位功能。SIP本身含有向注册服务器注册的功能,也可以利用其他定位服务器如DNS、LDAP等提供的定位服务器来增强其定位功能。<br>
<br>确定用户可用性:确定被叫会话终端是否可以参加此会话。SIP支持多种地址描述和寻址,包括:用户名@主机地址、被叫号码@PSTN网关地址和普通电话号码-01012345678描述等。这样SIP主叫按照被叫信息识别出被叫是否在传统电话网上,然后通过一个与传统电话网相连的网关向被叫发起呼叫。<br>
确定用户能力:确定被叫终端可用于参加会话的媒体类型及媒体参数。SIP终端在消息交互过程中携带自身的媒体类型和媒体参数,这使得会话都可以明确对方的会话能力。<br>
建立会话:建立主被叫双方的会话参数。SIP会话双方通过协商媒体类型和媒体参数,最终选择双方都具有的能力建立起会话。<br>
管理会话:可以更改会话参数或中止会话。
基本方法
REGISTER:注册联系信息。<br>
INVITE: 初始化一个会话。<br>
ACK: 对INVITE消息的最终响应。<br>
CANCEL: 终止一个等待处理或正在处理的请求。<br>
BYE: 终止一个会话。<br>
OPTIONS: 查询服务器的性能。
扩展方法
SUBSCRIBE:订阅方法
NOTIFY: 事件通知方法
MESSAGE: 即时消息方法
响应码状态
100~199: 报告,表明请求已经收到、继续处理请求<br>200~299: 成功,表明行为已经成功收到,理解和接受<br>300~399: 重定向,表明为完成呼叫请求,还需要采取的进一步动作<br>400~499: 客户端错误,表明请求有语法或不能被服务器执行。客户端需要修 改请求,然后重发请求<br>500~599: 服务端错误,表明服务器出错,不能执行合法请求<br>600~699: 全局性错误<br>
SIP请求的标题头
6个必须标题头: From、To、Call-ID、CSeq、Via、Max-Forwards
注册信令消息示范
VIA域:包含了Alice接收发送请求的服务器地址(pc33.atlanta.com)。同样这个包含了一个分支参数来标志Alice和这个服务器的会话事务。<br><br>TO域:包含了显示姓名(Bob)和一个SIP或者SIPS URI(sip:bob@biloxi.com)请求将首先传输到这个URI中。显示姓名(Display names)在RFC 2822中描述。<br><br>From域:也同样包含一个显示姓名(Alice)和一个SIP或者SIPS URI(sip:alice@atlanta.com)这个URI用来标志请求的原始发起者。<br>这个域也包含了一个TAG参数,这个TAG参数是一个随机字串(1928301774),是软电话(softphone)在URI上增加的一个随机串。用来做标志用途的。<br><br>Call_ID:包含一个全局的唯一标志,用来唯一标志这个呼叫,通过随机字串和softphone的自己名字或者IP抵制混和产生的。通过TO TAG, FROM TAG和CALL-ID完整定义了Alice和Bob之间的端到端的SIP关系,并且表示这个是一个对话性质的关系。<br><br>CSEQ或者Command Sequence:包含了一个整数和一个请求名字。这个Cseq数字是顺序递增的。每当对话中发起一个新的请求会引起这个数字顺序递增。<br><br>Contact:域包含一个SIP或者SIPS URI用来表示访问Alice的直接方式,通常由用户名和一个主机的全名(Fully Qualified Domain Name FQDN)组成。当FQDN作为首选的时候,许多终端用户由于不会由名字登记(而导致不能访问Alice的主机),所以IP地址是可选的。<br>
HTTP协议
孤单小弟 — HTTP
浏览器做的第一步工作是解析 URL
首先浏览器做的第一步工作就是要对 URL 进行解析,从而生成发送给 Web 服务器的请求信息。
一条长长的 URL 里的各个元素实际上是请求服务器里的文件资源,见下图:
生产 HTTP 请求信息
对 URL 进行解析之后,浏览器确定了 Web 服务器和文件名,接下来就是根据这些信息来生成 HTTP 请求消息了。
一个孤单 HTTP 数据包没有停滞不前,选择继续踏上茫茫征途,继续探索!
真实地址查询 — DNS
DNS 的由来
通过浏览器解析 URL 并生成 HTTP 消息后,需要委托操作系统将消息发送给 Web 服务器。
但在发送之前,还有一项工作需要完成,那就是 <b>查询服务器域名对应的 IP 地址</b>,<br>因为委托操作系统发送消息时,必须提供通信对象的 IP 地址。
所以,有一种服务器就专门 <b>保存了 Web 服务器域名与 IP 的对应关系</b>,它就是 <b>DNS 服务器</b>。
域名的层级关系
DNS 中的域名都是用句点来分隔的,比如 www.server.com,这里的句点代表了不同层次之间的界限。<br>在域名中,<b>越靠右 </b>的位置表示其 <b>层级越高</b>。<br>
实际上域名最后还有一个点,比如 www.server.com.,这个最后的一个点代表根域名。<br>也就是,. 根域是在最顶层,它的下一层就是 .com 顶级域,再下面是 server.com。
所以域名的层级关系类似一个树状结构:<br><ul><li>根 DNS 服务器(.)</li><li>顶级域 DNS 服务器(.com)</li><li>权威 DNS 服务器(server.com)</li></ul>
域名解析的工作流程<br>
1. 客户端首先会发出一个 DNS 请求,问 www.server.com 的 IP 是啥,并发给本地 DNS 服务器<br> (也就是客户端的 TCP/IP 设置中填写的 DNS 服务器地址)。
2. 本地域名服务器收到客户端的请求后,如果 <b>缓存里 </b>的表格能找到 www.server.com,则它直接返回 IP 地址。<br> 如果没有,<b>本地 DNS 会去问它的根域名服务器</b>:“老大, 能告诉我 www.server.com 的 IP 地址吗?” <br><b> 根域名服务器是最高层次的,它不直接用于域名解析,但能指明一条道路</b>。
3. 根 DNS 收到来自本地 DNS 的请求后,发现后置是 .com,说:“www.server.com 这个域名归 .com 区域管理”,<br> 我给你 .com 顶级域名服务器地址给你,你去问问它吧。”
4. 本地 DNS 收到顶级域名服务器的地址后,发起请求问“老二, 你能告诉我 www.server.com 的 IP 地址吗?”
5. 顶级域名服务器说:“我给你负责 server.com 区域的权威 DNS 服务器的地址,你去问它应该能问到”。
6. 本地 DNS 于是转向问权威 DNS 服务器:“老三,www.server.com对应的IP是啥呀?” <br> server.com 的权威 DNS 服务器,它是域名解析结果的原出处。为啥叫权威呢?就是我的域名我做主。
7. 权威 DNS 服务器查询后将对应的 IP 地址 X.X.X.X 告诉本地 DNS。
8. 本地 DNS 再将 IP 地址返回客户端,客户端和目标建立连接。
图解:
DNS 域名解析的过程蛮有意思的,整个过程就和我们日常生活中找人问路的过程类似,<b>只指路不带路</b>。
是不是每次解析域名都要经过那么多的步骤呢?
当然不是了,还有缓存这个东西的嘛。<br><br>浏览器会 <b>先看自身有没有对这个域名的缓存</b>,如果有,就直接返回,<br>如果没有,就 <b>去问操作系统</b>,操作系统也会去看自己的缓存,如果有,就直接返回,<br>如果没有,<b>再去 hosts 文件看</b>,也没有,<b>才会去问「本地 DNS 服务器」</b>。<br>
数据包表示:“DNS 老大哥厉害呀,找到了目的地了!我还是很迷茫呀,我要发出去,接下来我需要谁的帮助呢?”
指南好帮手 — 协议栈
通过 DNS 获取到 IP 后,就可以把 HTTP 的传输工作交给操作系统中的 <b>协议栈</b>。
协议栈的内部分为几个部分,分别承担不同的工作。上下关系是有一定的规则的,<br>上面的部分会向下面的部分委托工作,下面的部分收到委托的工作并执行。
应用程序(浏览器)通过调用 Socket 库,来委托协议栈工作。协议栈的上半部分有两块,<br>分别是负责收发数据的 TCP 和 UDP 协议,这两个传输协议会接受应用层的委托执行收发数据的操作。
协议栈的下半部分是用 IP 协议控制网络包收发操作,在互联网上传数据时,数据会被切分成一块块的网络包,<br>而将网络包发送给对方的操作就是由 IP 负责的。
此外 IP 中还包括 ICMP 协议和 ARP 协议:<br><ul><li>ICMP 用于告知网络包传送过程中产生的错误以及各种控制信息。</li><li>ARP 用于根据 IP 地址查询相应的以太网 MAC 地址。</li></ul>
IP 下面的网卡驱动程序负责控制网卡硬件,而最下面的网卡则负责完成实际的收发操作,<br>也就是对网线中的信号执行发送和接收操作。
数据包看了这份指南表示:“原来我需要那么多大佬的协助啊,那我先去找找 TCP 大佬!”<br>
可靠传输 — TCP
HTTP 是基于 TCP 协议传输的,所以在这我们先了解下 TCP 协议。
TCP 包头格式
TCP 报文头部的格式:
首先,<b>源端口号 </b>和 <b>目标端口号</b> 是不可少的,如果没有这两个端口号,数据就不知道 <b>应该发给哪个应用</b>。
接下来有包的 <b>序号</b>,这个是为了 <b>解决包乱序的问题</b>。
还应该有的是 <b>确认号</b>,目的是确认发出去对方是否有收到。如果没有收到就应该重新发送,<br>直到送达,这个是为了 <b>解决不丢包的问题</b>。
接下来还有一些 <b>状态位</b>。例如 SYN 是发起一个连接,ACK 是回复,RST 是重新连接,FIN 是结束连接等。<br>TCP 是面向连接的,因而 <b>双方要维护连接的状态</b>,这些带状态位的包的发送,会引起双方的状态变更。
还有一个重要的就是 <b>窗口大小</b>。TCP 要做 <b>流量控制</b>,通信双方各声明一个窗口(缓存大小),<br>标识自己当前能够的处理能力,别发送的太快,撑死我,也别发的太慢,饿死我。
除了做流量控制以外,TCP还会做 <b>拥塞控制</b>,对于真正遇到通路堵车,它无能为力,<br>唯一能做的就是控制自己,也即 <b>控制发送的速度</b>。不能改变世界,就改变自己嘛。
<b>TCP 传输数据之前,要先三次握手建立连接</b>
在 HTTP 传输数据之前,首先需要 TCP 建立连接,TCP 连接的建立,通常称为 <b>三次握手</b>。
这个所谓的「连接」,只是双方计算机里维护一个状态机,在连接建立的过程中,双方的状态变化时序图就像这样。<br>
一开始,客户端和服务端都处于 CLOSED 状态。先是服务端主动监听某个端口,处于 LISTEN 状态。
然后客户端主动发起连接 SYN,之后处于 SYN-SENT 发送状态。
服务端收到发起的连接,返回 SYN,并且 ACK 客户端的 SYN,之后处于 SYN-RCVD 接收状态。
客户端收到服务端发送的 SYN 和 ACK 之后,发送对 SYN 确认的 ACK,<br>之后处于 ESTABLISHED 已确立状态,因为它一发一收成功了。
服务端收到客户端对 SYN 确认的 ACK 之后,处于 ESTABLISHED 已确立状态,因为它也一发一收了。
所以三次握手目的是 <b>保证双方都有发送和接收的能力</b>。<br>
如何查看 TCP 的连接状态?
TCP 的连接状态查看,在 Linux 可以通过 netstat -napt 命令查看。
TCP 分割数据
如果 HTTP 请求消息比较长,超过了 MSS 的长度,这时 TCP 就需要把 HTTP 的数据<br>拆解成一块块的数据发送,而不是一次性发送所有数据。<br><ul><li>MTU:一个网络包的最大长度,以太网中一般为 1500 字节。</li><li>MSS:除去 IP 和 TCP 头部之后,一个网络包所能容纳的 TCP 数据的最大长度。</li></ul>
数据会被以 MSS 的长度为单位进行拆分,拆分出来的每一块数据都会被放进单独的网络包中。<br>也就是在每个被拆分的数据加上 TCP 头信息,然后交给 IP 模块来发送数据。
TCP 报文生成<br>
TCP 协议里面会有两个端口,一个是浏览器监听的端口(通常是随机生成的),一个<br>是 Web 服务器监听的端口(HTTP 默认端口号是 80, HTTPS 默认端口号是 443)。
在双方建立了连接后,TCP 报文中的数据部分就是存放 HTTP 头部 + 消息体,<br>组装好 TCP 报文之后,就需交给下面的网络层处理。
至此,网络包的报文如下图:<br>
此时,遇上了 TCP 的 数据包激动表示:“太好了,碰到了可靠传输的 TCP 传输,它给我加上 TCP 头部,<br>我不再孤单了,安全感十足啊!有大佬可以保护我的可靠送达!但我应该往哪走呢?”
远程地位 — IP
TCP 模块在执行连接、收发、断开等各阶段操作时,都需要委托 IP 模块将数据封装成 <b>网络包 </b>发送给通信对象。
IP 包头格式<br>
IP 报文头部的格式:
在 IP 协议里面需要有源地址 IP 和 目标地址 IP:<br><ul><li>源地址IP,即是客户端输出的 IP 地址;</li><li>目标地址,即通过 DNS 域名解析得到的 Web 服务器 IP。<br></li></ul>
因为 HTTP 是经过 TCP 传输的,所以在 IP 包头的协议号,要填写为 06(十六进制),表示协议为 TCP。
假设客户端有多个网卡,就会有多个 IP 地址,那 IP 头部的 <b>源地址 </b>应该选择哪个 IP 呢?
这个判断相当于在多块网卡中判断应该使用哪个一块网卡来发送包。<br>这个时候就需要根据路由表规则,来判断哪一个网卡作为源地址 IP。<br>
在 Linux 操作系统,我们可以使用 route -n 命令查看当前系统的路由表。
举个例子,根据上面的路由表,我们假设 Web 服务器的 <b>目标地址 </b>是 192.168.10.200。
首先先和第一条目的地的子网掩码(Genmask)进行 <b>与运算</b>,得到结果为 192.168.10.0,<br>但是第一个条目的地 Destination 是 192.168.3.0,两者不一致所以匹配失败。
再与第二条目的地的子网掩码进行 <b>与运算</b>,得到的结果为 192.168.10.0,与第二条目的地<br>Destination 192.168.10.0 匹配成功,所以将使用 eth1 网卡的 IP 地址作为 IP 包头的源地址。
第三条目比较特殊,它目标地址和子网掩码都是 0.0.0.0,这表示 <b>默认网关</b>,如果其他所有条目都无法匹配,<br>就会自动匹配这一行。并且后续就把包发给路由器,Gateway 即是路由器的 IP 地址。
IP 报文生成<br>
至此,网络包的报文如下图:
此时,加上了 IP 头部的数据包表示 :“有 IP 大佬给我指路了,感谢 IP 层给我加上了 IP 包头,<br>让我有了远程定位的能力!不会害怕在浩瀚的互联网迷茫了!可是目的地好远啊,我下一站应该去哪呢?”
两点传输 — MAC
生成了 IP 头部之后,接下来网络包还需要在 IP 头部的前面加上 MAC 头部。
MAC 包头格式<br>
MAC 头部是以太网使用的头部,它包含了接收方和发送方的 MAC 地址等信息。
在 MAC 包头里需要 <b>发送方 MAC 地址 </b>和 <b>接收方目标 MAC 地址</b>,用于 <b>两点之间的传输</b>。
一般在 TCP/IP 通信里,MAC 包头的 <b>协议类型 </b>只使用:<br><ul><li>0800 : IP 协议</li><li>0806 : ARP 协议</li></ul>
MAC 发送方和接收方如何确认?<br>
发送方的 MAC 地址获取就比较简单了,MAC 地址是在网卡生产时写入到 ROM 里的,<br>只要将这个值读取出来写入到 MAC 头部就可以了。
接收方的 MAC 地址就有点复杂了,只要告诉以太网对方的 MAC 的地址,<br>以太网就会帮我们把包发送过去,那么很显然这里应该填写对方的 MAC 地址。
所以先得搞清楚应该把包发给谁,这个只要查一下路由表就知道了。在路由表<br>中找到相匹配的条目,然后把包发给 Gateway 列中的 IP 地址就可以了。
<b>既然知道要发给谁,按如何获取对方的 MAC 地址呢?</b><br>
不知道对方 MAC 地址?不知道就喊呗。<br>此时就需要 ARP 协议帮我们找到路由器的 MAC 地址。
ARP 协议会在以太网中以 <b>广播</b> 的形式,对以太网所有的设备喊出:“这个 IP 地址是谁的?请把你的 MAC 地址告诉我”。<br><br>然后就会有人回答:“这个 IP 地址是我的,我的 MAC 地址是 XXXX”。<br><br>如果对方和自己处于同一个子网中,那么通过上面的操作就可以得到对方的 MAC 地址。<br>然后,我们将这个 MAC 地址写入 MAC 头部,MAC 头部就完成了。
<b>好像每次都要广播获取,这不是很麻烦吗?</b><br>放心,在后续操作系统会把本次查询结果放到一块叫做 ARP 缓存的内存空间留着以后用,不过缓存的时间就几分钟。<br><br>也就是说,在发包时:<br><ul><li>先查询 ARP 缓存,如果其中已经保存了对方的 MAC 地址,就不需要发送 ARP 查询,直接使用 ARP 缓存中的地址。</li><li>而当 ARP 缓存中不存在对方 MAC 地址时,则发送 ARP 广播查询。</li></ul>
在 Linux 系统中,我们可以使用 arp -a 命令来查看 ARP 缓存的内容。<br>
MAC 报文生成<br>
至此,网络包的报文如下图:
此时,加上了 MAC 头部的数据包万分感谢,说道 :“感谢 MAC 大佬,我知道我下一步要去哪了!<br>我现在有很多头部兄弟,相信我可以到达最终的目的地!”。 带着众多头部兄弟的数据包,终于准备要出门了。
出口 — 网卡
网络包只是存放在内存中的一串二进制数字信息,没有办法直接发送给对方。因此,我们<br>需要将 <b>数字信息转换为电信号</b>,才能在网线上传输,也就是说,这才是真正的数据发送过程。
负责执行这一操作的是 <b>网卡</b>,要控制网卡还需要靠 <b>网卡驱动程序</b>。
网卡驱动获取网络包之后,会将其 <b>复制 </b>到网卡内的缓存区中,接着会在<br>其 <b>开头加上报头和起始帧分界符,在末尾加上用于检测错误的帧校验序列</b>。<br><ul><li>起始帧分界符是一个用来表示包起始位置的标记</li><li>末尾的 FCS(帧校验序列)用来检查包传输过程是否有损坏</li></ul>
最后网卡会将包转为电信号,通过网线发送出去。<br>
送别者 — 交换机
交换机基本原理
<b>交换机(Switch)是一种用于局域网(LAN)的网络设备,它主要用于在局域网内部传输数据。</b><br>
交换机工作在 MAC 层,也称为二层网络设备。
交换机的包接收操作<br>
首先,电信号到达网线接口,交换机里的模块进行接收,接下来交换机里的模块将电信号转换为数字信号。
然后通过包末尾的 FCS 校验错误,如果没问题则放到缓冲区。<br>这部分操作基本和计算机的网卡相同,但交换机的工作方式和网卡不同。
<ul><li>计算机的网卡本身具有 MAC 地址,并通过核对收到的包的接收方 MAC <br>地址判断是不是发给自己的,如果不是发给自己的则丢弃;</li><li>相对地,<b>交换机的端口不核对接收方 MAC 地址</b>,而是 <b>直接接收所有的<br>包并存放到缓冲区中</b><b>包并存放到缓冲区中</b>。</li><li>因此,和网卡不同,<b>交换机的端口不具有 MAC 地址</b>。</li></ul>
将包存入缓冲区后,接下来需要查询一下这个包的接收方 MAC 地址是否已经在 MAC 地址表中有记录了。
交换机的 MAC 地址表主要包含两个信息:<br><ul><li>一个是设备的 MAC 地址</li><li>另一个是该设备连接在交换机的哪个端口上</li></ul>
举个例子,如果收到的包的接收方 MAC 地址为 00-02-B3-1C-9C-F9,则与图中表中的第 3 行匹配,<br>根据端口列的信息,可知这个地址位于 3 号端口上,然后就可以通过交换电路将包发送到相应的端口了。
所以,<b>交换机根据 MAC 地址表查找 MAC 地址,然后将信号发送到相应的端口</b>。
当 MAC 地址表找不到指定的 MAC 地址会怎么样?<br>
地址表中找不到指定的 MAC 地址。这可能是因为具有该地址的设备还没有向交换机发送过包,<br>或者这个设备一段时间没有工作导致地址被从地址表中删除了。<br><br>这种情况下,交换机无法判断应该把包转发到哪个端口,只能将包转发到<b>除了源端口之外的所有端口上</b>,<br>无论该设备连接在哪个端口上都能收到这个包。
这样做不会产生什么问题,因为以太网的设计本来就是将包发送到整个网络的,<br>然后 <b>只有相应的接收者才接收包,而其他设备则会忽略这个包。</b>
这样做会发送多余的包,会不会造成网络拥塞呢?
其实完全不用过于担心,因为发送了包之后目标设备会作出响应,只要返回了响应包,<br>交换机就可以将它的地址写入 MAC 地址表,下次也就不需要把包发到所有端口了。
局域网中每秒可以传输上千个包,多出一两个包并无大碍。<br>
此外,如果接收方 MAC 地址是一个 <b>广播地址</b>,那么交换机会将包发送到除源端口之外的所有端口。<br><br>以下两个属于广播地址:<br><ul><li>MAC 地址中的 FF:FF:FF:FF:FF:FF</li><li>IP 地址中的 255.255.255.255</li></ul>
数据包通过交换机转发抵达了路由器,准备要离开土生土长的子网了。此时,数据包<br>和交换机离别时说道:“感谢交换机兄弟,帮我转发到出境的大门,我要出远门啦!”
出境大门 — 路由器
路由器基本原理<br>
路由器(Router)是一种用于广域网(WAN)的网络设备,它主要用于在不同的网络之间进行数据传输。他具有IP和MAC地址。
当转发包时,首先路由器端口会<b>接收以太网包</b>,然后通过<b>路由表</b>查询转发目标,<br>再由相应的端口作为<b>发送方将以太网包发送出去</b>。
路由器与交换机的区别<br>
交换机主要工作在数据链路层,通过MAC地址进行数据转发,适用于局域网内部的数据交换;<br>而路由器主要工作在网络层,通过IP地址进行数据转发,适用于不同网络之间的数据交换。<br>
<ul><li>因为路由器是基于 IP 设计的,俗称三层网络设备,<b>路由器的各个端口都具有 MAC 地址和 IP 地址</b>;</li><li>而交换机是基于以太网设计的,俗称二层网络设备,<b>交换机的端口不具有 MAC 地址</b>。</li></ul>
路由器还具有网络地址转换(NAT)和防火墙等功能,可以提供更多的网络安全性。
路由器的包接收操作<br>
首先,电信号到达网线接口部分,路由器中的模块会将电信号转成数字信号,<br>然后通过包末尾的 FCS 进行错误校验。
如果没问题则检查 MAC 头部中的 <b>接收方 MAC 地址</b>,看看是不是发给自己的包,<br>如果是就放到接收缓冲区中,否则就丢弃这个包。
总的来说,路由器的端口都具有 MAC 地址,只接收与自身地址匹配的包,遇到不匹配的包则直接丢弃。
查询路由表确定输出端口<br>
完成包接收操作之后,路由器就会 <b>去掉 </b>包开头的 <b>MAC 头部</b>。
<b>MAC 头部的作用就是将包送达路由器</b>,其中的接收方 MAC 地址就是路由器端口的 MAC 地址。<br>因此,当包到达路由器之后,MAC 头部的任务就完成了,于是 <b>MAC 头部就会被丢弃</b>。
接下来,路由器会根据 MAC 头部后方的 <b>IP 头部 </b>中的内容进行包的转发操作。
转发操作分为几个阶段,首先是 <b>查询路由表 </b>判断转发目标。具体地流程如下图:
假设地址为 10.10.1.101 的计算机要向地址为 192.168.1.100 的服务器发送一个包,这个包先到达图中的路由器。
判断转发目标的第一步,就是根据包的接收方 IP 地址查询路由表中的目标地址栏,以找到相匹配的记录。
路由匹配和前面讲 IP 的匹配一样,每个条目的 <b>子网掩码和 192.168.1.100 IP 做 & 与运算 </b>后,得到的结果与对应<br>条目的目标地址进行匹配,如果匹配就会作为候选转发目标,如果不匹配就继续与下个条目进行路由匹配。<br>
如第二条目的子网掩码 255.255.255.0 与 192.168.1.100 IP 做 & 与运算后,得到结果是 192.168.1.0 ,<br>这与第二条目的目标地址 192.168.1.0 匹配,该第二条目记录就会被作为转发目标。
实在找不到匹配路由时,就会选择默认路由,路由表中子网掩码为 0.0.0.0 的记录表示「默认路由」。
路由器的发送操作<br>
接下来就会进入包的 <b>发送操作</b>。<br><br>首先,我们需要根据 <b>路由表的网关列 </b>判断对方的地址。<br><ul><li>如果网关是一个 IP 地址,则这个IP 地址就是我们要转发到的目标地址,<br>还未抵达终点,还需继续需要路由器转发。</li><li>如果网关为空,则 IP 头部中的接收方 IP 地址就是要转发到的目标地址,<br>也是就终于找到 IP 包头里的目标地址了,说明已抵达终点。</li></ul>
知道对方的 IP 地址之后,接下来需要通过 ARP 协议根据 IP 地址查询 MAC 地址,并将查询的结果作为接收方 MAC 地址。
路由器也有 ARP 缓存,因此首先会在 ARP 缓存中查询,如果找不到则发送 ARP 查询请求。<br>
接下来是发送方 MAC 地址字段,这里填写输出端口的 MAC 地址。<br>还有一个以太类型字段,填写 0800 (十六进制)表示 IP 协议。
网络包完成后,接下来会将其转换成电信号并通过端口发送出去。这一步的工作过程和计算机也是相同的。
发送出去的网络包会通过 <b>交换机 </b>到达下一个路由器。由于接收方 MAC 地址就是<br>下一个路由器的地址,所以交换机会根据这一地址将包传输到下一个路由器。
接下来,下一个路由器会将包转发给再下一个路由器,经过层层转发之后,网络包就到达了最终的目的地。
在网络包传输的过程中,<b>源 IP 和目标 IP 始终是不会变的</b>,<b>一直变化的是 MAC 地址</b>,<br>因为需要 MAC 地址在以太网内进行 <b>两个设备 </b>之间的包传输。
数据包通过多个路由器道友的帮助,在网络世界途经了很多路程,最终抵达了目的地的城门!<br>城门值守的路由器,发现了这个小兄弟数据包原来是找城内的人,于是它就将数据包送进了城内,<br>再经由城内的交换机帮助下,最终转发到了目的地了。数据包感慨万千的说道:“多谢这一路上,各路大侠的相助!”
互相扒皮 — 服务器与客户端
数据包抵达了服务器,服务器肯定高兴呀,正所谓有朋自远方来,不亦乐乎?
数据包抵达服务器后,服务器会先扒开数据包的 MAC 头部,查看是否和服务器自己的 MAC 地址符合,符合就将包收起来。
接着继续扒开数据包的 IP 头,发现 IP 地址符合,根据 IP 头中协议项,知道自己上层是 TCP 协议。<br>
于是,扒开 TCP 的头,里面有序列号,需要看一看这个序列包是不是我想要的,如果是就放入缓存中<br>然后返回一个 ACK,如果不是就丢弃。TCP头部里面还有端口号, HTTP 的服务器正在监听这个端口号。
于是,服务器自然就知道是 HTTP 进程想要这个包,于是就将包发给 HTTP 进程。
服务器的 HTTP 进程看到,原来这个请求是要访问一个页面,于是就把这个网页封装在 HTTP 响应报文里。
HTTP 响应报文也需要穿上 TCP、IP、MAC 头部,不过这次是源地址是<br>服务器 IP 地址,目的地址是客户端 IP 地址。
最后,客户端要离开了,向服务器发起了 TCP 四次挥手,至此双方的连接就断开了。<br>
一个数据包(我)凑不要脸的感受
我一开始我虽然孤单、不知所措,但没有停滞不前。我依然满怀信心和勇气开始了征途。<br>(你当然有勇气,你是应用层数据,后面有底层兄弟当靠山!)
我很庆幸遇到了各路神通广大的大佬,有可靠传输的 TCP
<font color="#0d0b22">有远程定位功能的 IP</font><br>
<font color="#0d0b22">有指明下一站位置的 MAC 等</font>
WebSockect协议
Socket背景
Socket<br>
Socket 是网络通信的基本单元,它为不同主机上的进程提供了一种通信机制。Socket 编程涉及到创建一个 Socket,通过它可以发送和接收数据。<br>
在网络通信中,主要有两种类型的 Socket:<br>
TCP Socket:提供可靠的、面向连接的通信。<br>
UDP Socket:提供不可靠的、无连接的通信。
WebSocket 请求是通过这些 Socket 进行通信的具体实现。<br>
WebSocket 是一种在单个 TCP 连接上提供全双工通信的协议。<br>WebSocket 它通常用于需要持久连接的应用,比如实时聊天、游戏、股票行情推送等。<br>WebSocket 连接是通过 HTTP 请求升级(HTTP Upgrade)建立的。客户端发送一个 HTTP 请求,请求升级到 WebSocket 协议,服务器同意并建立 WebSocket 连接。
WebSocket基本原理
WebSocket 是一种在单个 TCP 连接上提供全双工通信的协议。它的诞生解决了传统 HTTP 协议在通信中的局限性。<br>
初始提案(2008):<br>Michael Carter 提出了 WebSocket 的初始草案,旨在解决在 Web 上进行实时双向通信的问题。<br>
正式标准化(2011):<br>IETF 发布了 RFC 6455,正式定义了 WebSocket 协议。<br>WebSocket API 由 W3C 标准化,使得浏览器可以通过 JavaScript 使用 WebSocket。<br>
广泛支持:<br>随着 HTML5 的推广和浏览器的更新,WebSocket 得到了广泛的支持。现代主流浏览器(Chrome、Firefox、Safari、Edge)都实现了 WebSocket 支持。
WebSocket 和 HTTP 有着紧密的关系,尤其是在连接建立阶段:<br>
初始握手:<br>
WebSocket 连接从一个标准的 HTTP 请求开始,客户端通过发送 HTTP 请求来请求协议升级。<br><br>GET /chat HTTP/1.1<br>Host: server.example.com<br>Upgrade: websocket<br>Connection: Upgrade<br>Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==<br>Sec-WebSocket-Version: 13
协议升级:<br>
服务器接收到请求后,进行必要的校验,如果同意升级,则返回 101 Switching Protocols 响应。<br><br>HTTP/1.1 101 Switching Protocols<br>Upgrade: websocket<br>Connection: Upgrade<br>Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
连接建立:<br>
协议升级完成后,HTTP 连接变为 WebSocket 连接。<br><br>在这个阶段,连接从单向的 HTTP 通信变为全双工的 WebSocket 通信,客户端和服务器可以相互发送消息。<br>HTTP 通信结束。连接仍然存在,但接下来的数据交换将使用 WebSocket 完全独立的协议(定义在 RFC 6455 中)的二进制帧格式进行传输。
Http长连接原理<br>
Http长连接会话中,客户端和服务器之间可以保持连接状态,多次响应(请求)可以复用同一个连接。
HTTP/1.1版本默认使用长连接,而HTTP/1.0版本默认使用短连接。
这样可以减少每次请求的连接建立和断开的开销,提高数据传输效率。
查看HTTP头部中的Connection字段。如果Connection字段的值为"keep-alive",则表示该连接是长连接;<br>
如果Connection字段的值为"close",则表示该连接是短连接,即每次请求结束后都会关闭连接。
WebSocket 对比 Http
使用场景<br>
HTTP 长连接:<br><br>传统 Web 应用:适合一般的WEB资源加载、API 请求等。<br>频率较低的请求:适合频率较低的请求,连接保持打开以减少连接建立的开销。<br>
WebSocket:<br><br>实时应用:适合需要实时数据传输的应用,如实时聊天、在线游戏、股票行情推送等。<br>高频率的数据传输:适合高频率的数据传输场景,通过低开销的帧传输提高效率。
1. 通信模式<br>
HTTP 长连接:<br><br><b>请求-响应模式:HTTP 长连接依然遵循传统的请求-响应模式。客户端发送请求,服务器返回响应。连接保持开放以便后续请求可以复用同一个连接。<br></b>Connection: keep-alive:HTTP/1.1 默认支持长连接,通过 Connection: keep-alive 头部字段保持连接打开,以减少重复的 TCP 连接建立和关闭的开销。<br>
WebSocket:<br><br><b>全双工通信:WebSocket 建立连接后,客户端和服务器可以随时相互发送消息,无需等待对方的响应。<br></b>连接升级:WebSocket 连接从 HTTP 请求开始,通过 Upgrade 头部字段将协议从 HTTP 升级到 WebSocket。<br>
2. 连接建立<br>
HTTP 长连接:<br><br><b>标准的 HTTP 连接:通过标准的 HTTP 请求和响应建立连接,使用 Connection: keep-alive 头部字段来保持连接。<br>每次请求仍然独立:尽管连接保持打开,但每次请求-响应仍然是独立的,服务器处理完请求后需要返回响应。</b><br>
WebSocket:<br><br><b>初始握手:客户端发送 HTTP 请求,包含 Upgrade: websocket 头部字段,服务器响应 101 Switching Protocols 状态码,升级到 WebSocket 协议。<br>持久连接:握手成功后,建立持久的 WebSocket 连接,可以在这个连接上进行多次双向通信,直到显式关闭。</b>
3. 数据传输效率<br>
HTTP 长连接:<br><br><b>头部开销较大:每个请求和响应都包含头部字段,导致每次传输的额外开销较大。<br></b>适合较少的请求频率:长连接减少了重复建立和关闭连接的开销,但仍适合较少频率的请求场景。<br>
WebSocket:<br><br><b>低头部开销:数据帧的头部非常小,传输效率高,适合高频率的实时数据传输。<br></b>实时性强:支持实时性强的应用,如在线游戏、实时聊天、股票行情等。
Stream流接口的实现讨论
Stream是一种更通用的概念,它可以指代各种不同的数据流传输方式。
Stream可以是单向的,也可以是双向的。
Stream可以是持续的,也可以是一次性的。
Stream可以基于不同的协议实现,比如HTTP、SSE、WebSocket等。
HTTP 流式:<br><br>协议:基于 HTTP/1.1 协议。<br>连接:一次 HTTP 请求保持连接,服务器持续发送数据。可传输大量数据。<br><b>传输模式:单向数据流,通常是服务器向客户端持续传输数据。</b><br>
HTTP实现:使用 StreamingResponse 或类似机制逐步发送数据 + stop reason。
SSE实现:使用 StreamingResponse 且使用SSE Item规范 (使用json obj)。
单向的
HTTP协议的一种用法
纯文本
浏览器API:EventSource 相对简单
示例
WebSocket 流式:<br><br>协议:基于 WebSocket 协议(独立于 HTTP,但初始握手通过 HTTP 完成)。<br>连接:建立后是持久的双向连接。都可以发送数据。<br><b>传输模式:全双工通信,客户端和服务器都可以主动发送数据。</b>
WebSocket实现:通过 WebSocket 连接进行双向实时通信。
双向的
独立的WebSocket协议,握手后脱离HTTP
二进制帧
浏览器API: WebSocket 相对复杂,需要处理连接状态
示例
应用场景区分
结构化数据持续更新,大数据流 ✅ JSON 流<br>
实时生成 AI 回答(如 ChatGPT 类似效果) ✅ JSON 流 ✅ SSE<br>
实时日志输出 ✅ SSE<br>
实时股票行情推送 ✅ SSE<br>
需要自定义事件类型的通知 ✅ SSE ✅ JSON 流
实时聊天(双向) ❌ SSE(建议用 ✅WebSocket)<br>
游戏交互(双向) ❌ SSE(建议用 ✅WebSocket)<br>
0 条评论
下一页