<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ 计算机网络 - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ freeCodeCamp 是一个免费学习编程的开发者社区，涵盖 Python、HTML、CSS、React、Vue、BootStrap、JSON 教程等，还有活跃的技术论坛和丰富的社区活动，在你学习编程和找工作时为你提供建议和帮助。 ]]>
        </description>
        <link>https://www.freecodecamp.org/chinese/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ 计算机网络 - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/chinese/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Tue, 26 May 2026 16:03:47 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/chinese/news/tag/computer-networking/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ 子网检查单 - 24 子网掩码、30、26、27、29 和其他 IP 地址 CIDR 网络参考资料 ]]>
                </title>
                <description>
                    <![CDATA[ 作为开发人员或网络工程师，你可能需要时不时查阅子网掩码值并弄清其含义。 为了让你的生活更轻松，freeCodeCamp 社区制作了这个简单的备忘单。只需滚动或使用 Ctrl/Cmd + F 查找你要查找的值即可。 CIDR子网掩码通配符掩码IP 地址数量可用 IP 地址数量/32255.255.255.2550.0.0.011/31255.255.255.254 0.0.0.122*/30255.255.255.2520.0.0.342/29255.255.255.2480.0.0.786/28 255.255.255.2400.0.0.151614/27255.255.255.2240.0.0.313230/26255.255.255.192 0.0.0.636462/25255.255.255.1280.0.0.127128126/24255.255.255.00.0.0.255256254/23 255.255.254.00.0.1.255512510/22255.255.252.00.0.3.2551,0241,022/21255.255.248.0 0.0.7.2552, ]]>
                </description>
                <link>https://www.freecodecamp.org/chinese/news/subnet-cheat-sheet-24-subnet-mask-30-26-27-29-and-other-ip-address-cidr-network-references/</link>
                <guid isPermaLink="false">66835c6d9100b5049d88a6f8</guid>
                
                    <category>
                        <![CDATA[ 计算机网络 ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Miya Liu ]]>
                </dc:creator>
                <pubDate>Mon, 13 Jan 2025 08:59:00 +0000</pubDate>
                <media:content url="https://chinese.freecodecamp.org/news/content/images/2024/10/5f9c9647740569d1a4ca10a9.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>原文：</strong> <a href="https://www.freecodecamp.org/news/subnet-cheat-sheet-24-subnet-mask-30-26-27-29-and-other-ip-address-cidr-network-references/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">Subnet Cheat Sheet – 24 Subnet Mask, 30, 26, 27, 29, and other IP Address CIDR Network References</a>
      </p><!--kg-card-begin: markdown--><p>作为开发人员或网络工程师，你可能需要时不时查阅子网掩码值并弄清其含义。</p>
<p>为了让你的生活更轻松，freeCodeCamp 社区制作了这个简单的备忘单。只需滚动或使用 Ctrl/Cmd + F 查找你要查找的值即可。</p>
<table>
<thead>
<tr>
<th>CIDR</th>
<th>子网掩码</th>
<th>通配符掩码</th>
<th>IP 地址数量</th>
<th>可用 IP 地址数量</th>
</tr>
</thead>
<tbody>
<tr>
<td>/32</td>
<td>255.255.255.255</td>
<td>0.0.0.0</td>
<td>1</td>
<td>1</td>
</tr>
<tr>
<td>/31</td>
<td>255.255.255.254</td>
<td>0.0.0.1</td>
<td>2</td>
<td>2*</td>
</tr>
<tr>
<td>/30</td>
<td>255.255.255.252</td>
<td>0.0.0.3</td>
<td>4</td>
<td>2</td>
</tr>
<tr>
<td>/29</td>
<td>255.255.255.248</td>
<td>0.0.0.7</td>
<td>8</td>
<td>6</td>
</tr>
<tr>
<td>/28</td>
<td>255.255.255.240</td>
<td>0.0.0.15</td>
<td>16</td>
<td>14</td>
</tr>
<tr>
<td>/27</td>
<td>255.255.255.224</td>
<td>0.0.0.31</td>
<td>32</td>
<td>30</td>
</tr>
<tr>
<td>/26</td>
<td>255.255.255.192</td>
<td>0.0.0.63</td>
<td>64</td>
<td>62</td>
</tr>
<tr>
<td>/25</td>
<td>255.255.255.128</td>
<td>0.0.0.127</td>
<td>128</td>
<td>126</td>
</tr>
<tr>
<td>/24</td>
<td>255.255.255.0</td>
<td>0.0.0.255</td>
<td>256</td>
<td>254</td>
</tr>
<tr>
<td>/23</td>
<td>255.255.254.0</td>
<td>0.0.1.255</td>
<td>512</td>
<td>510</td>
</tr>
<tr>
<td>/22</td>
<td>255.255.252.0</td>
<td>0.0.3.255</td>
<td>1,024</td>
<td>1,022</td>
</tr>
<tr>
<td>/21</td>
<td>255.255.248.0</td>
<td>0.0.7.255</td>
<td>2,048</td>
<td>2,046</td>
</tr>
<tr>
<td>/20</td>
<td>255.255.240.0</td>
<td>0.0.15.255</td>
<td>4,096</td>
<td>4,094</td>
</tr>
<tr>
<td>/19</td>
<td>255.255.224.0</td>
<td>0.0.31.255</td>
<td>8,192</td>
<td>8,190</td>
</tr>
<tr>
<td>/18</td>
<td>255.255.192.0</td>
<td>0.0.63.255</td>
<td>16,384</td>
<td>16,382</td>
</tr>
<tr>
<td>/17</td>
<td>255.255.128.0</td>
<td>0.0.127.255</td>
<td>32,768</td>
<td>32,766</td>
</tr>
<tr>
<td>/16</td>
<td>255.255.0.0</td>
<td>0.0.255.255</td>
<td>65,536</td>
<td>65,534</td>
</tr>
<tr>
<td>/15</td>
<td>255.254.0.0</td>
<td>0.1.255.255</td>
<td>131,072</td>
<td>131,070</td>
</tr>
<tr>
<td>/14</td>
<td>255.252.0.0</td>
<td>0.3.255.255</td>
<td>262,144</td>
<td>262,142</td>
</tr>
<tr>
<td>/13</td>
<td>255.248.0.0</td>
<td>0.7.255.255</td>
<td>524,288</td>
<td>524,286</td>
</tr>
<tr>
<td>/12</td>
<td>255.240.0.0</td>
<td>0.15.255.255</td>
<td>1,048,576</td>
<td>1,048,574</td>
</tr>
<tr>
<td>/11</td>
<td>255.224.0.0</td>
<td>0.31.255.255</td>
<td>2,097,152</td>
<td>2,097,150</td>
</tr>
<tr>
<td>/10</td>
<td>255.192.0.0</td>
<td>0.63.255.255</td>
<td>4,194,304</td>
<td>4,194,302</td>
</tr>
<tr>
<td>/9</td>
<td>255.128.0.0</td>
<td>0.127.255.255</td>
<td>8,388,608</td>
<td>8,388,606</td>
</tr>
<tr>
<td>/8</td>
<td>255.0.0.0</td>
<td>0.255.255.255</td>
<td>16,777,216</td>
<td>16,777,214</td>
</tr>
<tr>
<td>/7</td>
<td>254.0.0.0</td>
<td>1.255.255.255</td>
<td>33,554,432</td>
<td>33,554,430</td>
</tr>
<tr>
<td>/6</td>
<td>252.0.0.0</td>
<td>3.255.255.255</td>
<td>67,108,864</td>
<td>67,108,862</td>
</tr>
<tr>
<td>/5</td>
<td>248.0.0.0</td>
<td>7.255.255.255</td>
<td>134,217,728</td>
<td>134,217,726</td>
</tr>
<tr>
<td>/4</td>
<td>240.0.0.0</td>
<td>15.255.255.255</td>
<td>268,435,456</td>
<td>268,435,454</td>
</tr>
<tr>
<td>/3</td>
<td>224.0.0.0</td>
<td>31.255.255.255</td>
<td>536,870,912</td>
<td>536,870,910</td>
</tr>
<tr>
<td>/2</td>
<td>192.0.0.0</td>
<td>63.255.255.255</td>
<td>1,073,741,824</td>
<td>1,073,741,822</td>
</tr>
<tr>
<td>/1</td>
<td>128.0.0.0</td>
<td>127.255.255.255</td>
<td>2,147,483,648</td>
<td>2,147,483,646</td>
</tr>
<tr>
<td>/0</td>
<td>0.0.0.0</td>
<td>255.255.255.255</td>
<td>4,294,967,296</td>
<td>4,294,967,294</td>
</tr>
</tbody>
</table>
<ul>
<li>/31 是 <a href="https://datatracker.ietf.org/doc/html/rfc3021">RFC 3021</a> 中详细说明的一种特殊情况，这种子网掩码类型的网络可以分配两个 IP 地址作为点对点链路。</li>
</ul>
<p>以下是子网掩码和通配符的十进制到二进制的转换表：</p>
<table>
<thead>
<tr>
<th></th>
<th>子网掩码</th>
<th></th>
<th>通配符</th>
</tr>
</thead>
<tbody>
<tr>
<td>0</td>
<td>00000000</td>
<td>255</td>
<td>11111111</td>
</tr>
<tr>
<td>128</td>
<td>10000000</td>
<td>127</td>
<td>01111111</td>
</tr>
<tr>
<td>192</td>
<td>11000000</td>
<td>63</td>
<td>00111111</td>
</tr>
<tr>
<td>224</td>
<td>11100000</td>
<td>31</td>
<td>00011111</td>
</tr>
<tr>
<td>240</td>
<td>11110000</td>
<td>15</td>
<td>00001111</td>
</tr>
<tr>
<td>248</td>
<td>11111000</td>
<td>7</td>
<td>00000111</td>
</tr>
<tr>
<td>252</td>
<td>11111100</td>
<td>3</td>
<td>00000011</td>
</tr>
<tr>
<td>254</td>
<td>11111110</td>
<td>1</td>
<td>00000001</td>
</tr>
<tr>
<td>255</td>
<td>11111111</td>
<td>0</td>
<td>00000000</td>
</tr>
</tbody>
</table>
<p>注意，通配符只是子网掩码的反码。</p>
<p>如果你是网络工程的新手，你可以<a href="https://www.freecodecamp.org/news/computer-networks-and-how-to-actually-understand-them-c1401908172d/">在这里更好地了解计算机网络的工作原理</a>。</p>
<p>最后，这张速查表和本文的其余部分重点介绍的是 IPv4 地址，而不是较新的 IPv6 协议。如果你想了解更多关于 IPv6 的信息，请查看上面关于计算机网络的文章。</p>
<h2 id="ip">IP 地址块如何工作？</h2>
<p>像 <code>192.168.0.1</code> 这样的 IPv4 地址实际上只是四个二进制块的十进制表示。</p>
<p>每个块是 8 位，表示从 0-255 的数字。由于这些块是 8 位的组，每个块被称为一个<strong>八位</strong>。由于有四个 8 位的块，每个 IPv4 地址共有 32 位。</p>
<p>例如，以下是 IP 地址 <code>172.16.254.1</code> 的二进制格式：</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/03/1125px-Ipv4_address.png" alt="1125px-Ipv4_address" width="600" height="400" loading="lazy"></p>
<p>来源：<a href="https://www.wikiwand.com/en/articles/IPv4">IPv4</a></p>
<p>要将 IP 地址在十进制和二进制形式之间转换，可以使用下图：</p>
<table>
<thead>
<tr>
<th>128</th>
<th>64</th>
<th>32</th>
<th>16</th>
<th>8</th>
<th>4</th>
<th>2</th>
<th>1</th>
</tr>
</thead>
<tbody>
<tr>
<td>x</td>
<td>x</td>
<td>x</td>
<td>x</td>
<td>x</td>
<td>x</td>
<td>x</td>
<td>x</td>
</tr>
</tbody>
</table>
<p>上图表示一个 8 位的八位字节。</p>
<p>现在假设你要转换 IP 地址 <code>168.210.225.206</code>。你只需要将地址分成四块（<code>168</code>、<code>210</code>、<code>225</code> 和 <code>206</code>），并且使用上图将每一块转换为二进制。</p>
<p>记住在二进制中，1 等同于“开”，0 等同于“关”。所以要将第一个块 <code>168</code> 转换为二进制，只需从图表的开头开始，在单元格中放置 1 或 0，直到总和为 <code>168</code>。</p>
<p>例如：</p>
<table>
<thead>
<tr>
<th>128</th>
<th>64</th>
<th>32</th>
<th>16</th>
<th>8</th>
<th>4</th>
<th>2</th>
<th>1</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>0</td>
<td>1</td>
<td>0</td>
<td>1</td>
<td>0</td>
<td>0</td>
<td>0</td>
</tr>
</tbody>
</table>
<p>128 + 32 + 8 = 168，在二进制中是 <code>10101000</code>。</p>
<p>如果对其余的块进行同样的操作，你会得到 <code>10101000.11010010.11100001.11001110</code>。</p>
<p>如果你看上面的表格，可能会觉得 IP 地址的数量几乎是无限的。毕竟，IPv4 地址有将近42亿个可用地址。</p>
<p>但是，考虑到互联网的发展，以及如今有多少设备连接到网络，当你听到已经存在 <a href="https://whatismyipaddress.com/ipv4-shortage">IPv4 地址短缺</a>，可能也不会感到惊讶。</p>
<p>因为开发人员多年前就已经意识到了短缺问题，他们想出了一个方法，将一个 IP 地址拆分成更小的网络，叫作“子网”。</p>
<p>这个过程叫作“子网划分”，使用 IP 地址的主机部分将其分解成更小的网络或子网。</p>
<p>通常，IP 地址由网络位和主机位组成：</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/03/network-and-host-bits.png" alt="network-and-host-bits" width="600" height="400" loading="lazy"></p>
<p>来源：<a href="https://support.huawei.com/enterprise/en/doc/EDOC1100145159">什么是 IPv4</a></p>
<p>所以，一般来说，子网划分有两个作用：它为我们提供了一种将网络拆分成子网的方法，并允许设备确定另一个设备/IP 地址是否在同一个本地网络上。</p>
<p>在没有子网划分的情况下，每个连接到互联网的设备都需要一个独特的 IP 地址。</p>
<p>但由于你有一个无线路由器，你只需要一个为你的路由器分配的 IP 地址。这个公共或外部 IP 地址通常是自动处理的，并由你的互联网服务提供商（ISP）分配。</p>
<p>然后每个连接到该路由器的设备都有其自己的私有或内部 IP 地址：</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/03/home-network-diagram.png" alt="home-network-diagram" width="600" height="400" loading="lazy"></p>
<p>来源：<a href="https://www.popularmechanics.com/technology/a32729384/how-to-find-ip-address/">我的 IP 地址是什么？</a></p>
<p>现在如果内部 IP 地址为 <code>192.168.1.101</code> 的设备想要与另一台设备通信，它将使用另一台设备的 IP 地址和子网掩码。</p>
<p>IP 地址和子网掩码的组合使得 <code>192.168.1.101</code> 设备能够判断其他设备是否在同一个网络中（例如 <code>192.168.1.103</code> 设备），或者是在互联网上其他地方的完全不同的网络中。</p>
<p>有趣的是，你的 ISP 为你的路由器分配的外部 IP 地址可能是某个子网的一部分，该子网可能包括附近家庭或企业的许多其他 IP 地址。和内部 IP 地址一样，它也需要一个子网掩码才能工作。</p>
<p>子网掩码可以被视为 IP 地址的一种过滤器。通过子网掩码，设备可以查看 IP 地址，并弄清楚哪些部分是网络位，哪些部分是主机位。</p>
<p>然后利用这些信息，设备可以确定最佳的通信方式。</p>
<p>如果你曾浏览过路由器或计算机上的网络设置，你可能见过这个数字：<code>255.255.255.0</code>。</p>
<p>如果见过，你已经看到了一个非常常见的适用于简单家庭网络的子网掩码。</p>
<p>像 IPv4 地址一样，子网掩码也是 32 位。就像将 IP 地址转换为二进制一样，你也可以对子网掩码进行相同的转换。</p>
<p>例如，这里是我们之前的图表：</p>
<table>
<thead>
<tr>
<th>128</th>
<th>64</th>
<th>32</th>
<th>16</th>
<th>8</th>
<th>4</th>
<th>2</th>
<th>1</th>
</tr>
</thead>
<tbody>
<tr>
<td>x</td>
<td>x</td>
<td>x</td>
<td>x</td>
<td>x</td>
<td>x</td>
<td>x</td>
<td>x</td>
</tr>
</tbody>
</table>
<p>现在让我们转换第一个八比特，255：</p>
<table>
<thead>
<tr>
<th>128</th>
<th>64</th>
<th>32</th>
<th>16</th>
<th>8</th>
<th>4</th>
<th>2</th>
<th>1</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
</tr>
</tbody>
</table>
<p>很简单，对吧？所以任何一个八比特中的 <code>255</code> 在二进制中就是 <code>11111111</code>。这意味着 <code>255.255.255.0</code> 在二进制中实际上是 <code>11111111.11111111.11111111.00000000</code>。</p>
<p>以下是这两者的十进制和二进制表示：</p>
<table>
<thead>
<tr>
<th>类型</th>
<th>十进制</th>
<th>二进制</th>
</tr>
</thead>
<tbody>
<tr>
<td>IP 地址</td>
<td>192.168.0.101</td>
<td>11000000.10101000.00000000.01100101</td>
</tr>
<tr>
<td>子网掩码</td>
<td>255.255.255.0</td>
<td>11111111.11111111.11111111.00000000</td>
</tr>
</tbody>
</table>
<p>这样排列后，很容易将 <code>192.168.0.101</code> 分成网络位和主机位。</p>
<p>只要二进制子网掩码中的某位为 1，二进制 IP 地址中的相同位就是网络的一部分，而不是主机的一部分。</p>
<p>由于八比特 <code>255</code> 的二进制形式是 <code>11111111</code>，所以 IP 地址中的整个八比特都是网络的一部分。因此，前三个八比特 <code>192.168.0</code> 是 IP 地址的网络部分，而 <code>101</code> 是主机部分。</p>
<p>换句话说，如果设备 <code>192.168.0.101</code> 想与另一个设备进行通信，使用子网掩码它知道任何IP地址为 <code>192.168.0.xxx</code> 的设备都在同一个本地网络上。</p>
<p>另一种表达方式是使用网络ID，它只是IP地址的网络部分。所以IP地址 <code>192.168.0.101</code> 的网络ID，子网掩码为 <code>255.255.255.0</code>，即 <code>192.168.0.0</code>。</p>
<h3 id="cidrcidr">CIDR 是什么及 CIDR 表示法？</h3>
<p><strong>CIDR</strong> 是无类域间路由的缩写，使用于 IPv4，最近也用于 IPv6 路由。</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/05/1920px-IP_Address_Match.svg.png" alt="1920px-IP_Address_Match.svg" width="600" height="400" loading="lazy"></p>
<p>来源：<a href="https://www.wikiwand.com/zh/articles/%E6%97%A0%E7%B1%BB%E5%88%AB%E5%9F%9F%E9%97%B4%E8%B7%AF%E7%94%B1">无类别域间路由</a></p>
<p>CIDR 于 1993 年引入，作为缓解 IPv4 地址消耗的一种方式。在此之前，互联网使用的是旧有的分类 IP 地址系统，该系统导致 IPv4 地址迅速枯竭。</p>
<p>CIDR 涵盖了几个主要概念。</p>
<p>第一个是可变长度子网掩码（VLSM），这基本上允许网络工程师在子网内创建子网。那些子网可以有不同的大小，从而减少了未使用的 IP 地址数量。</p>
<p>CIDR 引入的第二个主要概念是 CIDR 表示法。</p>
<p>CIDR 表示法实际上只是子网掩码的简写，表示 IP 地址可用的位数。例如，<code>192.168.0.101/24</code> 中的 <code>/24</code> 相当于 IP 地址 <code>192.168.0.101</code> 和子网掩码 <code>255.255.255.0</code>。</p>
<h3 id="cidr">CIDR 的计算方法</h3>
<p>要计算子网掩码的 CIDR 表示法，只需将子网掩码转换为二进制，然后计算其中的 1 的数量即可。例如：</p>
<table>
<thead>
<tr>
<th>类型</th>
<th>十进制</th>
<th>二进制</th>
</tr>
</thead>
<tbody>
<tr>
<td>子网掩码</td>
<td>255.255.255.0</td>
<td>11111111.11111111.11111111.00000000</td>
</tr>
</tbody>
</table>
<p>由于有三个八比特是 1，所以有 24 个 "on" 位，这意味着 CIDR 表示法为 <code>/24</code>。</p>
<p>你可以用任何一种方式书写，但我相信你会同意用 <code>/24</code> 比写 <code>255.255.255.0</code> 要简单很多。</p>
<p>这通常是在使用 IP 地址时进行的，所以让我们看看带有 IP 地址的相同子网掩码：</p>
<table>
<thead>
<tr>
<th>类型</th>
<th>十进制</th>
<th>二进制</th>
</tr>
</thead>
<tbody>
<tr>
<td>IP 地址</td>
<td>192.168.0.101</td>
<td>11000000.10101000.00000000.01100101</td>
</tr>
<tr>
<td>子网掩码</td>
<td>255.255.255.0</td>
<td>11111111.11111111.11111111.00000000</td>
</tr>
</tbody>
</table>
<p>子网掩码的前三个八比特全是 "on" 位，这意味着 IP 地址的前三个八比特全是网络位。</p>
<p>让我们更详细地看看最后的第四个八比特：</p>
<table>
<thead>
<tr>
<th>类型</th>
<th>十进制</th>
<th>二进制</th>
</tr>
</thead>
<tbody>
<tr>
<td>IP 地址</td>
<td>101</td>
<td>01100101</td>
</tr>
<tr>
<td>子网掩码</td>
<td>0</td>
<td>00000000</td>
</tr>
</tbody>
</table>
<p>在这种情况下，由于子网掩码中这个八比特的所有比特都是 “off”，我们可以确定 IP 地址中这个八比特的所有相应比特都是主机的一部分。</p>
<p>当你使用 CIDR 表示法时，通常会使用网络 ID。因此，IP 地址 <code>192.168.0.101</code> 和子网掩码 <code>255.255.255.0</code> 的 CIDR 表示法是 <code>192.168.0.0/24</code>。</p>
<p>若要查看更多关于如何计算给定 IP 地址和子网掩码的 CIDR 表示法和网络 ID 的示例，请观看以下视频：</p>
<figure class="kg-card kg-embed-card" data-test-label="fitted">
        <div class="fluid-width-video-container">
          <div style="padding-top: 56.17977528089888%;" class="fluid-width-video-wrapper">
            <iframe width="356" height="200" src="https://www.youtube.com/embed/XQ3T14SIlV4?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen="" name="fitvid0"></iframe>
          </div>
        </div>
      </figure>
<h2 id="ip">IP 地址分类</h2>
<p>现在我们已经了解了一些子网划分和 CIDR 的基本示例，让我们放大来看一下所谓的“分类网络”。</p>
<p>在开发子网划分之前，所有的 IP 地址都属于特定的类别：</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/03/subnetting.png" alt="subnetting" width="600" height="400" loading="lazy"></p>
<p>来源：<a href="https://community.spiceworks.com/t/subnetting-for-dummies/970210">简单子网划分教程</a></p>
<p>注意，这里还有 D 类和 E 类 IP 地址，但我们将在稍后详细介绍这些内容。</p>
<p>分类 IP 地址为网络工程师提供了一种为不同组织提供一系列有效 IP 地址的方法。</p>
<p>这个方法有很多问题，最终导致了子网划分的出现。但在我们深入探讨这些问题之前，让我们先仔细看看不同的 IP 地址类别。</p>
<h3 id="aip">A 类 IP 地址</h3>
<p>对于 A 类 IP 地址，前八位（8 位 / 1 字节）表示网络 ID，其余三段（24 位 / 3 字节）表示主机 ID。</p>
<p>A 类 IP 地址范围从 <code>1.0.0.0</code> 到 <code>127.255.255.255</code>，默认子网掩码为 <code>255.0.0.0</code>（或 CIDR 的 <code>/8</code>）。</p>
<p>这意味着 A 类地址可以有 128（2^7）个网络，每个网络有 16,777,214（2^24-2）个可用地址。</p>
<p>另外，请注意，在 A 类地址范围内，<code>127.0.0.0</code> 到 <code>127.255.255.255</code> 这一范围被保留用于主机循环地址（参见 <a href="https://datatracker.ietf.org/doc/html/rfc5735">RFC5735</a>）。</p>
<h3 id="bip">B 类 IP 地址</h3>
<p>对于 B 类 IP 地址，前两段（16 位 / 2 字节）表示网络 ID，其余两段（16 位 / 2 字节）表示主机 ID。</p>
<p>B 类 IP 地址范围从 <code>128.0.0.0</code> 到 <code>191.255.255.255</code>，默认子网掩码为 <code>255.255.0.0</code>（或 CIDR 的 <code>/16</code>）。</p>
<p>B 类寻址每个网络可有 16,384（2^14）个网络地址和 65,534（2^16）个可用地址。</p>
<h3 id="cip">C 类 IP 地址</h3>
<p>对于 C 类 IP 地址，前三个八位字节（24 位 / 3 字节）代表网络 ID，最后一个八位字节（8 位 / 1 字节）是主机 ID。</p>
<p>C 类 IP 地址的范围是从 <code>192.0.0.0</code> 到 <code>223.255.255.255</code>，默认子网掩码为 <code>255.255.255.0</code>（或 CIDR 记法中的 <code>/24</code>）。</p>
<p>C 类 IP 地址对应 2,097,152（2^21）个网络，每个网络有 254（2^8 - 2）个可用地址。</p>
<h3 id="deip">D 类和 E 类 IP 地址</h3>
<p>最后两类是 D 类和 E 类。</p>
<p>D 类 IP 地址保留用于多播。它们的范围是从 <code>224.0.0.0</code> 到 <code>239.255.255.255</code>。</p>
<p>E 类 IP 地址是实验性的，范围是 <code>240.0.0.0</code> 以上。</p>
<h3 id="ip">类划分 IP 地址的问题</h3>
<p>类划分 IP 地址的主要问题是不高效，会导致大量 IP 地址的浪费。</p>
<p>例如，设想你当时是一个大型组织的一部分。你的公司有 1,000 名员工，这意味着它属于 B 类。</p>
<p>但如果你往上看，你会发现 B 类网络可以支持多达 65,534 个可用地址。这远远超过了你的组织可能需要的数量，即使每个员工有多个带唯一地址的设备。</p>
<p>并且你的组织不可能退回到 C 类，因为没有足够的可用 IP 地址。</p>
<p>因此，当 IPv4 地址变得普及时，使用类 IP 地址的那段时间里，人们很快就意识到需要一个更好的系统来确保我们不会用光所有约 42 亿个可用地址。</p>
<p>自从类 IP 地址在 1993 年被 CIDR 取代后，就不再使用了，现在主要被研究用来理解早期互联网架构，以及为什么子网划分很重要。</p>
<h2 id="">希望这个速查表对你有所帮助</h2>
<p>如果你觉得这有帮助，请与朋友分享，让更多人从中受益。</p>
<p>此外，欢迎在 <a href="https://x.com/kriskoishigawa">Twitter</a> 上联系我，告诉我你的想法。</p>
<!--kg-card-end: markdown--> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Localhost 是什么 ]]>
                </title>
                <description>
                    <![CDATA[ 如果你是一个有经验的 web 开发者，那么你可能在很多场合看到过 “localhost” 这个词。 而即使你是一个初学者，刚刚开始接触 web 开发，你也可能在使用实时服务器插件时看到 “127.0.0.1:” 数字。 你可能在本地使用它来测试网站和 web 应用，却不知道它到底是什么。那么，“127.0.0.1” 就是 “localhost”，“localhost” 就是 “127.0.0.1”。 在这篇文章中，你将了解什么是 localhost，以及它对应的 IP地址 127.0.0.1。 Localhost 是什么 在计算机网络中，主机是指“服务器”。就像你可以把一个网站托管在一个服务器上，来把它放在互联网上，你可以让你自己的计算机成为那个服务器。这种连接被称为  loopback 回环。该回环的 IP 地址是 127.0.0.1。 如果你以前在互联网上放过一个网站，那么你已经和 Heroku、Hostinger、Netlify 等托管公司打过交道。这些就是我所说的“远程主机”或虚拟服务器。 如果你的电脑上有一个网站，这样你就可以在不连接互联网的情况下进行测试，你所面 ]]>
                </description>
                <link>https://www.freecodecamp.org/chinese/news/what-is-localhost/</link>
                <guid isPermaLink="false">64183c565e1a4c068f38d3e9</guid>
                
                    <category>
                        <![CDATA[ 计算机网络 ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Miya Liu ]]>
                </dc:creator>
                <pubDate>Fri, 17 Mar 2023 04:29:00 +0000</pubDate>
                <media:content url="https://chinese.freecodecamp.org/news/content/images/2023/03/localhost.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>原文：</strong> <a href="https://www.freecodecamp.org/news/what-is-localhost/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">https://www.freecodecamp.org/news/what-is-localhost/</a>
      </p><p>如果你是一个有经验的 web 开发者，那么你可能在很多场合看到过 “localhost” 这个词。</p><p>而即使你是一个初学者，刚刚开始接触 web 开发，你也可能在使用实时服务器插件时看到 “127.0.0.1:” 数字。</p><p>你可能在本地使用它来测试网站和 web 应用，却不知道它到底是什么。那么，“127.0.0.1” 就是 “localhost”，“localhost” 就是 “127.0.0.1”。</p><p>在这篇文章中，你将了解什么是 localhost，以及它对应的 IP地址 127.0.0.1。</p><h2 id="localhost-"><strong>Localhost 是什么</strong></h2><p>在计算机网络中，主机是指“服务器”。就像你可以把一个网站托管在一个服务器上，来把它放在互联网上，你可以让你自己的计算机成为那个服务器。这种连接被称为 <strong><strong>loopback</strong> 回环</strong>。该回环的 IP 地址是 <code>127.0.0.1</code>。</p><p>如果你以前在互联网上放过一个网站，那么你已经和 Heroku、Hostinger、Netlify 等托管公司打过交道。这些就是我所说的“远程主机”或虚拟服务器。</p><p>如果你的电脑上有一个网站，这样你就可以在不连接互联网的情况下进行测试，你所面对的就是一个本地主机。</p><p>因此，根据定义，localhost 是当前向自己发出请求的计算机或主机名。在这种情况下，这台电脑也是虚拟服务器。</p><h2 id="ip-127-0-0-1-"><strong>IP 地址 <code>127.0.0.1</code> 是什么</strong></h2><p>如果你想访问一个网站，你在浏览器的地址栏中输入网站地址，例如：<code>https://freecodecamp.org</code>。</p><p>域名服务器（DNS）将该地址与该名称对应的数字 IP 地址相匹配。在 freeCodeCamp 的例子中，这个IP地址是 <code>104.26.2.33</code>。你访问的每个网站都是这样做的。</p><p>localhost 也不例外。所以，如果你在浏览器的地址栏里输入 <code>localhost</code>，它就会转化为 IP 地址 <code>127.0.0.1</code>。</p><p>这个 <code>127.0.0.1</code> 的 IP 地址是为计算机的本地服务器保留的，所以你永远不会找到其他以 127 开头的 IP 地址。</p><h3 id="localhost-xxx-127-0-0-1-xxx-"><strong>localhost: xxx 或 127.0.0.1: xxx 是什么</strong></h3><p>就像 <code>HTTP</code> 和 <code>HTTPS</code> 一样，<code>localhost</code> 是一种协议。记住，网站域名是跟在 <code>http</code> 或 <code>https</code> 后面的，例如，<code>https://www.google.com/</code> 和 <code>https://www.freecodecamp.org/</code>。</p><p>所以，在 <code>localhost:</code> 和 <code>127.0.0.1:</code> 后面必须要有东西。那个东西就是端口号。</p><p>例如，在一个 Express 应用程序中，这个端口号就是你设置的端口变量，就像这样：</p><pre><code class="language-js">const port = 4000;
</code></pre><p>因此，如果你在浏览器地址栏中输入 <code>localhost:4000</code> 并点击 <code>ENTER</code>，就会显示你目前正在做的 web 应用：</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2022/06/ss1-5.png" class="kg-image" alt="ss1-5" width="600" height="400" loading="lazy"></figure><p>另外，如果你输入 <code>127.0.0.1:4000</code>，你会得到同样的回应：</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2022/06/ss2-5.png" class="kg-image" alt="ss2-5" width="600" height="400" loading="lazy"></figure><p>如果你用 VS Code 的实时服务器扩展，它使用连接到 <code>127.0.0.1</code> 的 <code>5500</code> 端口，后面是文件名：</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2022/06/ss3-6.png" class="kg-image" alt="ss3-6" width="600" height="400" loading="lazy"></figure><h2 id="-"><strong>总结</strong></h2><p>我希望这篇文章能帮助你了解更多关于 localhost 的信息，它的 IP 地址是什么，以及它是如何服务本地测试网站的。</p><p>还有，没有什么地方像 localhost。正确的说法是，“没有地方像 127.0.0.1 那样”:)。</p><p>继续编码......</p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ 如何让你的 Web 项目实现内网穿透 ]]>
                </title>
                <description>
                    <![CDATA[ 什么是内网穿透？  * 内网穿透，简单地说就是内网的数据让外网可以获取，可以映射到公共网络上，这样就可以在公共网络上访问内网的数据。  * 内网是不能被外网直接访问的，只能通过一些中转技术，如 DingTalk Design CLI、花生壳、Natap    等工具，让内网“假装”成外网，就是内网穿透。  * 外网主机的 IP 地址的一个端口映射到内网中一台机器，提供相应的服务。当用户访问该 IP 的这个端口时，服务器自动将请求映射到对应局域网内部的机器上。  * 内网穿透扩展了我们之前的工作场景和范围，让使用者可以不局限在内网环境中就可以做到局域网才能做的事情，大大提高了我们的效率。 -------------------------------------------------------------------------------- 内网穿透可以实现什么？  * 实现外网访问树莓派  * 教授远程访问学校的服务器  * 搭建个恋爱单页面站点，记录他跟她的恋爱故事  * 开发调试 web 站点  * 开发调试手机移动 APP  * 搭建一个临时的演示站点给客户看  *  ]]>
                </description>
                <link>https://www.freecodecamp.org/chinese/news/intranet-penetration/</link>
                <guid isPermaLink="false">62a86fa6150818084d6d4380</guid>
                
                    <category>
                        <![CDATA[ 计算机网络 ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ 陈俊雁 ]]>
                </dc:creator>
                <pubDate>Mon, 20 Jun 2022 03:27:45 +0000</pubDate>
                <media:content url="https://chinese.freecodecamp.org/news/content/images/2023/12/WechatIMG323.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <h2 id="-"><strong>什么是内网穿透？</strong></h2><ul><li>内网穿透，简单地说就是内网的数据让外网可以获取，可以映射到公共网络上，这样就可以在公共网络上访问内网的数据。</li><li>内网是不能被外网直接访问的，只能通过一些中转技术，如 DingTalk Design CLI、花生壳、Natap 等工具，让内网“假装”成外网，就是内网穿透。</li><li>外网主机的 IP 地址的一个端口映射到内网中一台机器，提供相应的服务。当用户访问该 IP 的这个端口时，服务器自动将请求映射到对应局域网内部的机器上。</li><li>内网穿透扩展了我们之前的工作场景和范围，让使用者可以不局限在内网环境中就可以做到局域网才能做的事情，大大提高了我们的效率。</li></ul><hr><h2 id="--1"><strong>内网穿透可以实现什么？</strong></h2><ul><li>实现外网访问树莓派</li><li>教授远程访问学校的服务器</li><li>搭建个恋爱单页面站点，记录他跟她的恋爱故事</li><li>开发调试 web 站点</li><li>开发调试手机移动 APP</li><li>搭建一个临时的演示站点给客户看</li><li>微信小程序开发方便调试</li><li>搭建“我的世界”私服</li></ul><hr><h2 id="come-on-web-"><strong>Come on ，让你的 WEB 项目实现内网穿透</strong></h2><p><strong>Wonderland</strong>：“创建一个能跑起来的网站，所以第一步就是把网站搭建起来。”</p><p><strong>YOU</strong>：“这简单呀！我三年前的时候就玩过，写个 index.html 然后在浏览器里打开不就完事了？”</p><p><strong>Wonderland</strong>：“那是在本地打开。你换别人电脑，还能访问吗？”</p><p><strong>YOU</strong>：“弄到 Gitee 或者 GitHub 不就行了……”</p><p><strong>Wonderland</strong>：“那 Gitee 用的什么你知道吗？”</p><p><strong>YOU</strong>：“这…… 不太懂欸”</p><p><strong>Wonderland</strong>：“打开浏览器的开发者工具，访问 Gitee，看看 Gitee.com 返回的 response，headers 里面，server 部分填的是什么？”</p><p><strong>You</strong>：“啥？开发者工具？Response header？跟不上了……”</p><p><strong>Wonderland</strong>：“哎，年轻人，程序员的修炼之路任重而道远啊……告诉你，是 <a href="https://www.nginx.com/">NGINX</a>” 。</p><figure class="kg-card kg-image-card kg-width-wide kg-card-hascaption"><img src="https://chinese.freecodecamp.org/news/content/images/2022/06/3-2.png" class="kg-image" alt="3-2" width="600" height="400" loading="lazy"><figcaption>Gitee.com 返回的 response，headers 里面，server 部分填的是什么？”</figcaption></figure><p><strong>Wonderland</strong>：“NGINX 是最流行的轻高性能 web 服务器，常常用来做反向代理、负载均衡等等。利用了 epoll API，异步模型，简直是高并发的最佳拍档……”</p><p><strong>You</strong>：“这……”</p><p><strong>Wonderland</strong>：“呃……是不是扯太多了？没关系，这些也不太重要，用得多了你就了解了。暂时就先从最简单的网站搭起吧——安装 NGINX”</p><h3 id="-nginx"><strong>安装及配置 NGINX</strong></h3><ol><li><strong>NGINX 下载地址 <a href="https://nginx.org/">https://nginx.org</a>，选择下载 nginx-1.22.0 稳定版</strong></li></ol><figure class="kg-card kg-image-card kg-width-wide kg-card-hascaption"><img src="https://chinese.freecodecamp.org/news/content/images/2022/06/2-1.png" class="kg-image" alt="2-1" width="600" height="400" loading="lazy"><figcaption>NGINX 下载</figcaption></figure><p>2. <strong> 配置 NGINX 访问本地资源</strong></p><p>修改 nginx.conf 配置文件，在 conf 目录下，基本上所有的配置都在这里面做。不同的版本或者不同的操作系统路径可能不一样 。</p><p>Windows 操作系统一般在这里：nginx-&gt; conf -&gt; nginx.conf</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://chinese.freecodecamp.org/news/content/images/2022/06/------.png" class="kg-image" alt="zhaoWenJian" width="600" height="400" loading="lazy"><figcaption>打开 nginx.conf 文件</figcaption></figure><p>打开 nginx.conf 之后，看到 root 后面的是 html，把 html 修改成你想要展示的前端项目的绝对路径。</p><p>像我这样修改 root , Nginx 会默认访问 C:\Users\Wonderland\Desktop\shen-zhen 下面的 index.html。</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://chinese.freecodecamp.org/news/content/images/2022/06/1.png" class="kg-image" alt="xiuGaiMuLu" width="600" height="400" loading="lazy"><figcaption>将 root内容，修改成本地项目的绝对路径 : C:\Users\Wonderland\Desktop\shen-zhen</figcaption></figure><p>2. &nbsp;<strong>启动 Nginx</strong></p><ul><li>Windows 启动 Nginx</li></ul><p>		Win + R 运行 cmd 命令窗口，切换到 nginx 目录下，输入命令 nginx.exe 或 start nginx。</p><ul><li>Mac OS 启动 Nginx</li></ul><p>		打开终端窗口，切换到 nginx 目录下，输入命令 sudo nginx。</p><p>4. &nbsp;<strong>访问 localhost</strong></p><p>在浏览器输入 localhost 就可以访问你刚刚在 root 里配置的前端项目</p><p>注意： 在 nginx.conf 文件内，nginx 默认配置的监听的端口为 80，如果 80 端口被占用，则会出现端口冲突。</p><figure class="kg-card kg-image-card kg-width-wide kg-card-hascaption"><img src="https://chinese.freecodecamp.org/news/content/images/2023/12/--2023-12-23-20.55.59.png" class="kg-image" alt="benDiDaKai" srcset="https://chinese.freecodecamp.org/news/content/images/size/w600/2023/12/--2023-12-23-20.55.59.png 600w, https://chinese.freecodecamp.org/news/content/images/size/w1000/2023/12/--2023-12-23-20.55.59.png 1000w, https://chinese.freecodecamp.org/news/content/images/size/w1600/2023/12/--2023-12-23-20.55.59.png 1600w, https://chinese.freecodecamp.org/news/content/images/size/w2400/2023/12/--2023-12-23-20.55.59.png 2400w" sizes="(min-width: 1200px) 1200px" width="600" height="400" loading="lazy"><figcaption>在浏览器上访问 localhost</figcaption></figure><p><strong>You</strong>：“我专门留着公司电脑没关机，但是一回家用自己的 Windows 笔记本还是访问不了，是哪设置得有问题吗？”</p><p><strong>Wonderland</strong>：“嗨，localhost 是本地主机，就是当前电脑的意思。别说回家用你的 Windows，就算换个同事的电脑，访问 localhost 也不可能行得通啊。”</p><p><strong>You</strong>：“我想到了这一点，所以专门提前看了主机的 IP 地址，是 192.168……”</p><p><strong>Wonderland</strong>：“那也不行的。192.168.xxx.xxx 这种都是内网 IP。在咱们公司内部别的电脑上，通过 IP 访问你电脑上的网站倒还行，但是出了公司就不行了。”</p><p><strong>You</strong>：“啊？为什么会这样呢？”</p><p><strong>Wonderland</strong>：“说来话长啊。一方面当然是安全的考虑，但其实也有历史原因。IP 地址总量是有限的，最早美国人研发出来的时候，没人知道这玩意将来会成为重要的资源，所以分配得很随意，后来才发现，有些不需要那么多 IP 的人攒了一大堆闲置的 IP，需要 IP 的人反而分配得远远不够。”</p><p><strong>You</strong>：“啊？不够？那怎么上网呢？”</p><p><strong>Wonderland</strong>：“后来为了解决这个问题，就发明了 NAT 技术，对外一个公网 IP，对内可以变成好多个内网 IP，相互之间做好转换就行了。”</p><p><strong>You</strong>：“唔……有点懵……”</p><p><strong>Wonderland</strong>：“嗯……反正你知道结果就行了——咱们的电脑都是没有公网 IP 的，只有内网IP，从外面访问不了。”</p><p><strong>You</strong>：“那怎么办呢？”</p><p><strong>Wonderland</strong>：“一般来说肯定不能让人随随便便进公司内网啊，安全起见嘛。不过……你要真想内网穿透的话，<a href="https://open.dingtalk.com/document/resourcedownload/http-intranet-penetration">钉钉</a>了解一下？”</p><figure class="kg-card kg-image-card"><img src="https://chinese.freecodecamp.org/news/content/images/2022/06/4.png" class="kg-image" alt="dingDing" width="600" height="400" loading="lazy"></figure><h3 id="--2"><strong>内网穿透</strong></h3><p>使用 DingTalk Design CLI 启动内网穿透，执行以下命令，下载 DingTalk Design CLI 工具。</p><ol><li><strong>安装</strong></li></ol><pre><code>npm install dingtalk-design-cli@latest -g</code></pre><p>执行以下命令，检测是否成功安装</p><pre><code>ding -v</code></pre><p>执行以下命令，启动钉钉内网穿透 这里最后的 80 是 Nginx 代理本地的端口号 80</p><pre><code>ding ngrok --subdomain xxxx --port 80
/*xxxxx可以写成任意字母*/</code></pre><blockquote>我写的是 <u>ding ngrok --subdomain chen --port 80（</u>xxxx在我这里就是 <em>chen）</em>。</blockquote><p>执行完该命令后，访问 xxxxx.vaiwan.cn 都会映射到 localhost（127.0.0.1:80）</p><p>注意：访问 xxxxx.vaiwan.cn 的时候使用 http 协议不是 https 协议。</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://chinese.freecodecamp.org/news/content/images/2022/06/6-1.png" class="kg-image" alt="DaKaiDing" width="600" height="400" loading="lazy"><figcaption>成功</figcaption></figure><p><strong>2. &nbsp;可能会遇到的问题</strong></p><p>如果出现这个就是服务器分配隧道失败，说明你的 xxxxx 已经被别人抢先占用了！换个名字就好了。</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://chinese.freecodecamp.org/news/content/images/2022/06/--------1--1.png" class="kg-image" alt="--------1--1" width="600" height="400" loading="lazy"><figcaption>服务器布局隧道失败</figcaption></figure><p><strong>3. &nbsp;映射</strong></p><p>现在你在本地修改项目文件，在本地上执行的所有修改也会映射到公共网络上。</p><figure class="kg-card kg-image-card kg-width-wide kg-card-hascaption"><img src="https://chinese.freecodecamp.org/news/content/images/2023/12/--2023-12-23-20.57.58.png" class="kg-image" alt="chengGongDing" srcset="https://chinese.freecodecamp.org/news/content/images/size/w600/2023/12/--2023-12-23-20.57.58.png 600w, https://chinese.freecodecamp.org/news/content/images/size/w1000/2023/12/--2023-12-23-20.57.58.png 1000w, https://chinese.freecodecamp.org/news/content/images/size/w1600/2023/12/--2023-12-23-20.57.58.png 1600w, https://chinese.freecodecamp.org/news/content/images/size/w2400/2023/12/--2023-12-23-20.57.58.png 2400w" sizes="(min-width: 1200px) 1200px" width="600" height="400" loading="lazy"><figcaption>（左图为 localhost 本地访问，右图为公网链接访问）</figcaption></figure><p><strong>4. &nbsp;React 项目内网</strong></p><p>我们先运行 react 项目文件 npm start，React 的 localhost 的默认端口是 :3000，可以借助钉钉内网穿透开发工具，就可以这样写，把后面的端口号改为 3000。</p><pre><code>ding ngrok --subdomain xxxxx --port 3000</code></pre> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ 什么是 FTP？文件传输协议和 FTP 服务器的含义 ]]>
                </title>
                <description>
                    <![CDATA[ 原文：What is FTP? File Transfer Protocol and FTP Server Meaning [https://www.freecodecamp.org/news/what-is-ftp-file-transfer-protocol-and-ftp-server-meaning/] ，作者：Ihechikara Vincent Abba [https://www.freecodecamp.org/news/author/ihechikara/] FTP 代表 File Transfer Protocol 文件传输协议。这是一种网络/通信协议，用于通过 TCP/IP（传输控制协议/Internet 协议）网络在计算机之间传输文件。 TCP/IP 网络的示例有：  * HTTP（超文本传输​​协议）  * HTTPS（安全超文本传输​​协议）  * FTP（文件传输协议） 文件传输协议如何工作？ 要使用 FTP 在计算机之间传输文件，你必须访问 FTP 服务器（我将在下面解释什么是 FTP 服务器）。 根据你访问的服务器类型，你可能需要输入用户名和密 ]]>
                </description>
                <link>https://www.freecodecamp.org/chinese/news/what-is-ftp-file-transfer-protocol-and-ftp-server-meaning/</link>
                <guid isPermaLink="false">626131c499ec7406219e74ee</guid>
                
                    <category>
                        <![CDATA[ 计算机网络 ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Miya Liu ]]>
                </dc:creator>
                <pubDate>Thu, 21 Apr 2022 10:20:00 +0000</pubDate>
                <media:content url="https://chinese.freecodecamp.org/news/content/images/2022/04/thisisengineering-raeng-zBLtU0zbJcU-unsplash--1-.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>原文：<a href="https://www.freecodecamp.org/news/what-is-ftp-file-transfer-protocol-and-ftp-server-meaning/">What is FTP? File Transfer Protocol and FTP Server Meaning</a>，作者：<a href="https://www.freecodecamp.org/news/author/ihechikara/">Ihechikara Vincent Abba</a></p><p>FTP 代表 File Transfer Protocol 文件传输协议。这是一种网络/通信协议，用于通过 TCP/IP（传输控制协议/Internet 协议）网络在计算机之间传输文件。</p><p>TCP/IP 网络的示例有：</p><ul><li>HTTP（超文本传输​​协议）</li><li>HTTPS（安全超文本传输​​协议）</li><li>FTP（文件传输协议）</li></ul><h2 id="-">文件传输协议如何工作？</h2><p>要使用 FTP 在计算机之间传输文件，你必须访问 FTP 服务器（我将在下面解释什么是 FTP 服务器）。</p><p>根据你访问的服务器类型，你可能需要输入用户名和密码才能访问服务器中的文件。在访问文件之前不需要任何身份验证的服务器连接被称为匿名 FTP。</p><p>当用户成功访问/登录到 FTP 服务器后，他们可以在服务器上下载或上传文件。</p><p>获取对 FTP 服务器的访问权限的一般方法有两种：</p><ul><li>通过网络浏览器。你可以通过在浏览器中输入服务器地址来完成此操作。该地址可能是 ftp.myftpfiles.com 或 https://www.myftpfiles.com。登录服务器之后，你就可以与所有者上传到服务器的文件进行交互。</li><li>通过 FTP 客户端。我们将在下一节讨论 FTP 客户端。</li></ul><h2 id="-ftp-">什么是 FTP 客户端？</h2><p>FTP 客户端是在请求访问的计算机和存储文件的服务器之间创建连接的软件。</p><p>有许多 FTP 客户端软件可供使用。它们提供了一个我们可以与之交互的图形用户界面 (GUI)。</p><p>下面，我们将了解 FTP 客户端的外观以及如何使用它。我们将使用 <a href="https://filezilla-project.org/">FileZilla</a>。</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2022/04/Screenshot--270--1.png" class="kg-image" alt="Screenshot--270--1" width="600" height="400" loading="lazy"></figure><p>在上图中，有不同的文本字段。<code>Host</code> 文本字段是输入服务器地址的地方。</p><p><code>Username</code> 和 <code>Password</code> 文本字段适用于在授予访问权限之前需要身份验证的服务器。</p><p><code>port</code> 文本字段通常为 21。这是 FTP 的专用端口。</p><p>填写必要的文本字段后，你可以单击 <code>Quickconnect</code> 以连接到服务器。</p><p>该软件的左侧是 <code>local site</code>，它是我的计算机，其中包含现有目录的列表。</p><p>右侧是 <code>Remote site</code>，其中将显示服务器中的所有信息和文件。</p><h2 id="-ftp--1">什么是 FTP 服务器？</h2><p>FTP 服务器基本上是最初上传所有文件的计算机。每个服务器都有一个 FTP 地址，用户可以通过浏览器或 FTP 客户端通过 TCP/IP 访问该地址。</p><p>服务器允许访问者下载和上传文件。</p><h2 id="ftp-">FTP 服务器安全吗？</h2><p>尽管许多 FTP 服务器都需要身份验证，但由于协议缺乏加密，它们并不安全。这使得存储在 FTP 服务器上的文件更有可能被第三方和不受欢迎的第三方访问。</p><p>FTP 最首选和更安全的协议是 SFTP，它代表安全文件传输协议，就像 HTTP 和 HTTPS 一样。</p><p>SFTP 更安全，因为存储在服务器上的数据是加密的。</p><p>其他替代方案包括：</p><ul><li>FTPS（安全文件传输协议）</li><li>HTTPS（安全超文本传输​​协议）</li><li>AS2（适用性声明 2）</li></ul><h2 id="-ftp--2">使用 FTP 的优势</h2><p>以下是使用 FTP 的一些优点：</p><ul><li>更快的文件传输</li><li>可以被众多主机支持</li><li>支持大文件传输</li><li>能够定时传送</li><li>传输中断时可以恢复</li></ul><h2 id="-ftp--3">使用 FTP 的缺点</h2><p>以下是使用 FTP 的一些缺点：</p><ul><li>FTP 服务器缺乏安全性</li><li>Chrome 和 Firefox 等主流浏览器不再支持 FTP</li><li>用户凭据和文件未加密</li><li>某些服务器可能包含有害文件</li></ul><h2 id="--1">结论</h2><p>在本文中，我们讨论了文件传输协议，它使我们能够通过网络在计算机之间传输文件。</p><p>我们看到了 FTP 客户端和 FTP 服务器是什么。我们还讨论了为什么 FTP 服务器不安全，以及我们可以使用的其他安全替代方案。</p><p>最后，我们了解了使用 FTP 的优点和缺点。</p><p>感谢你阅读本文！</p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ 详解 HTTP、HTTPS 和 HTTP2 ]]>
                </title>
                <description>
                    <![CDATA[ 你知道 HTTP 和 HTTPS 的区别吗？如果你想了解更多的计算机网络基础知识，那么你可能会想弄清楚这些概念。 在这篇文章中，我将尽量用通俗易懂的方式来向读者讲述 HTTP 的知识。我建议大家在学习 HTTP 知识的时候，利用 Chrome 开发者工具来做实践，这可以帮助我们理解得更深刻。 此图是在网上找来的，侵删HTTP 概述 HTTP 超文本传输​​协议是位于 TCP/IP 体系结构中的应用层协议，它是万维网数据通信的基础。 当我们访问一个网站时，需要通过统一资源定位符（uniform resource locator，URL）来定位服务器并获取资源。 <协议>://<域名>:<端口>/<路径> 一个 URL 的一般形式通常如上所示（http://test.com/index.html ），现在最常用的协议就是 HTTP，HTTP 的默认端口是 80，通常可以省略。 HTTP/1.1 HTTP/1.1 是目前使用最广泛的版本，一般没有特别标明版本都是指 HTTP/1.1。 HTTP 连接建立过程 我们来看一下在浏览器输入 URL 后获取 HTML 页面的过程。   ]]>
                </description>
                <link>https://www.freecodecamp.org/chinese/news/http-https-and-http2/</link>
                <guid isPermaLink="false">5fb235e95f583f056509114b</guid>
                
                    <category>
                        <![CDATA[ HTTP ]]>
                    </category>
                
                    <category>
                        <![CDATA[ HTTPS ]]>
                    </category>
                
                    <category>
                        <![CDATA[ 计算机网络 ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ woai3c ]]>
                </dc:creator>
                <pubDate>Thu, 19 Aug 2021 07:20:00 +0000</pubDate>
                <media:content url="https://chinese.freecodecamp.org/news/content/images/2021/04/photo-1593642533144-3d62aa4783ec-1.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>你知道 HTTP 和 HTTPS 的区别吗？如果你想了解更多的计算机网络基础知识，那么你可能会想弄清楚这些概念。</p><p>在这篇文章中，我将尽量用通俗易懂的方式来向读者讲述 HTTP 的知识。我建议大家在学习 HTTP 知识的时候，利用 Chrome 开发者工具来做实践，这可以帮助我们理解得更深刻。</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://pic2.zhimg.com/80/v2-8d547f61a175c4e6cc05ad90a7406791_720w.jpg" class="kg-image" alt="v2-8d547f61a175c4e6cc05ad90a7406791_720w" width="600" height="400" loading="lazy"><figcaption>此图是在网上找来的，侵删</figcaption></figure><h2 id="http-">HTTP 概述</h2><p>HTTP 超文本传输​​协议是位于 TCP/IP 体系结构中的应用层协议，它是万维网数据通信的基础。</p><p>当我们访问一个网站时，需要通过统一资源定位符（uniform resource locator，URL）来定位服务器并获取资源。</p><pre><code class="language-text">&lt;协议&gt;://&lt;域名&gt;:&lt;端口&gt;/&lt;路径&gt;</code></pre><p>一个 URL 的一般形式通常如上所示（<code>http://test.com/index.html</code> ），现在最常用的协议就是 HTTP，HTTP 的默认端口是 80，通常可以省略。</p><figure class="kg-card kg-image-card"><img src="https://pic1.zhimg.com/80/v2-91035fa397152281c18e1a2f9ece81f4_720w.jpg" class="kg-image" alt="v2-91035fa397152281c18e1a2f9ece81f4_720w" width="600" height="400" loading="lazy"></figure><h2 id="http-1-1">HTTP/1.1</h2><p>HTTP/1.1 是目前使用最广泛的版本，一般没有特别标明版本都是指 HTTP/1.1。</p><h3 id="http--1">HTTP 连接建立过程</h3><p>我们来看一下在浏览器输入 URL 后获取 HTML 页面的过程。</p><ol><li>先通过<a href="https://link.zhihu.com/?target=https%3A//baike.baidu.com/item/%25E5%259F%259F%25E5%2590%258D%25E7%25B3%25BB%25E7%25BB%259F%25EF%25BC%2588%25E6%259C%258D%25E5%258A%25A1%25EF%25BC%2589%25E5%258D%258F%25E8%25AE%25AE/15134609%3Ffromtitle%3Ddns%26fromid%3D427444" rel="nofollow noreferrer">域名系统（Domain Name System，DNS）</a>查询将域名转换为 IP 地址。即将 <code>test.com</code> 转换为 <code>221.239.100.30</code> 这一过程。</li><li>通过三次握手（稍后会讲）建立 TCP 连接。</li><li>发起 HTTP 请求。</li><li>目标服务器接收到 HTTP 请求并处理。</li><li>目标服务器往浏览器发回 HTTP 响应。</li><li>浏览器解析并渲染页面。</li></ol><p>下图中的 RTT 为往返时延（Round-Trip Time： 往返时延。表示从发送端发送数据开始，到发送端收到来自接收端的确认，总共经历的时延）。<br></p><figure class="kg-card kg-image-card"><img src="https://pic1.zhimg.com/80/v2-ddcb4a085bbde7f8bf80f792d4ac7e48_720w.jpg" class="kg-image" alt="v2-ddcb4a085bbde7f8bf80f792d4ac7e48_720w" width="600" height="400" loading="lazy"></figure><h3 id="http--2">HTTP 连接拆除过程</h3><p>所有 HTTP 客户端（浏览器）、服务器都可在任意时刻关闭 TCP 连接。通常会在一条报文结束时关闭连接，但出错的时候，也可能在首部行的中间或其他任意位置关闭连接。</p><h3 id="tcp-">TCP 三次握手和四次挥手</h3><p>由于 HTTP 是基于 TCP 的，所以打算在这补充一下 TCP 连接建立和拆除的过程。</p><p>首先，我们需要了解一些 TCP 报文段的字段和标志位：</p><ol><li>32 比特的序号字段和确认号字段，TCP 字节流每一个字节都按顺序编号。确认号是接收方期望从对方收到的下一字节的序号。</li><li>ACK 标志位，用于指示确认字段中的值是有效的 ACK=1 有效，ACK=0 无效。</li><li>SYN 标志位，用于连接建立，SYN 为 1 时，表明这是一个请求建立连接报文。</li><li>FIN 标志位，用于连接拆除，FIN 为 1 时，表明发送方数据已发送完毕，并要求释放连接。<br></li></ol><figure class="kg-card kg-image-card"><img src="https://pic4.zhimg.com/80/v2-578eeb6309c44c4607344fe019dff19b_720w.jpg" class="kg-image" alt="v2-578eeb6309c44c4607344fe019dff19b_720w" width="600" height="400" loading="lazy"></figure><h3 id="tcp--1">TCP 三次握手建立连接</h3><p>TCP 标准规定，ACK 报文段可以携带数据，但不携带数据就不用消耗序号。</p><ol><li>客户端发送一个不包含应用层数据的 TCP 报文段，首部的 SYN 置为 1，随机选择一个初始序号（一般为 0）放在 TCP 报文段的序号字段中。（SYN 为 1 的时候，不能携带数据，但要消耗掉一个序号）</li><li>TCP 报文段到达服务器主机后，服务器提取报文段，并为该 TCP 连接分配缓存和变量。然后向客户端发送允许连接的 ACK 报文段（不包含应用层数据）。这个报文段的首部包含 4 个信息：ACK 置 为 1，SYN 置为 1；确认号字段置为客户端的序号 + 1；随机选择自己的初始序号（一般为 0）。</li><li>收到服务器的 TCP 响应报文段后，客户端也要为该 TCP 连接分配缓存和变量，并向服务器发送一个 ACK 报文段。这个报文段将服务器端的序号 + 1 放置在确认号字段中，用来对服务器允许连接的报文段进行响应，因为连接已经建立，所以 SYN 置为 0。最后一个阶段，报文段可以携带客户到服务器的数据。并且以后的每一个报文段，SYN 都置为 0。</li></ol><p>下图是一个具体的示例：<br></p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://pic2.zhimg.com/80/v2-eb4981e4f58f1822c00d7d290d14ee51_720w.jpg" class="kg-image" alt="v2-eb4981e4f58f1822c00d7d290d14ee51_720w" width="600" height="400" loading="lazy"><figcaption>此截图是我使用 Wireshark 抓包工具截取的 TCP 报文段截图</figcaption></figure><h3 id="tcp--2">TCP 四次挥手拆除连接</h3><p>FIN 报文段即使不携带数据，也要消耗序号。</p><ol><li>客户端发送一个 FIN 置为 1 的报文段。</li><li>服务器回送一个确认报文段。</li><li>服务器发送 FIN 置为 1 的报文段。</li><li>客户端回送一个确认报文段。</li></ol><h3 id="tcp--3">TCP 为什么是四次挥手，而不是三次？</h3><ol><li>当 A 给 B 发送 FIN 报文时，代表 A 不再发送报文，但仍可以接收报文。</li><li>B 可能还有数据需要发送，因此先发送 ACK 报文，告知 A “我知道你想断开连接的请求了”。这样 A 便不会因为没有收到应答而继续发送断开连接的请求（即 FIN 报文）。</li><li>B 在处理完数据后，就向 A 发送一个 FIN 报文，然后进入 LAST_ACK 阶段（超时等待）。</li><li>A 向 B 发送 ACK 报文，双方都断开连接。</li></ol><p>参考资料：</p><ul><li><a href="https://www.zhihu.com/question/63264012">知乎网友-魔方的回答</a></li></ul><h3 id="http--3">HTTP 报文格式</h3><p>HTTP 报文由请求行、首部、实体主体组成，它们之间由 CRLF（回车换行符） 分隔开。</p><p><strong>注意：实体包括首部(也称为实体首部)和实体主体，sp 即是空格 space</strong>。<br></p><figure class="kg-card kg-image-card"><img src="https://pic1.zhimg.com/80/v2-392bc8d0de5ac6d44dd520ca4e42afc8_720w.jpg" class="kg-image" alt="v2-392bc8d0de5ac6d44dd520ca4e42afc8_720w" width="600" height="400" loading="lazy"></figure><p><br>请求行和首部是由 ASCII 文本组成的，实体主体是可选的，可以为空也可以是任意二进制数据。</p><p>请求报文和响应报文的格式基本相同。</p><p><strong>请求报文格式</strong>：</p><pre><code class="language-text">&lt;method&gt; &lt;request-URL&gt; &lt;version&gt;
&lt;headers&gt;
&lt;entity-body&gt;</code></pre><p><strong>响应报文格式</strong>：</p><pre><code class="language-text">&lt;version&gt; &lt;status&gt; &lt;reason-phrase&gt;
&lt;headers&gt;
&lt;entity-body&gt;</code></pre><p><strong>一个请求或响应报文由以下字段组成</strong>：</p><ol><li>请求方法，客户端希望服务器对资源执行的动作。</li><li>请求 URL，命名了所请求的资源。</li><li>协议版本，报文所使用的 HTTP 版本。</li><li>状态码，这三位数字描述了请求过程中所发生的情况。</li><li>原因短语，数字状态码的可读版本（例如上面的响应示例跟在 200 后面的 OK，一般按规范写最好）。</li><li>首部，可以有零或多个首部。</li><li>实体的主体部分，可以为空也可以包含任意二进制数据。</li></ol><p><strong>一个 HTTP 请求示例</strong>：</p><pre><code class="language-text">GET /2.app.js HTTP/1.1
Host: 118.190.217.8:3389
Connection: keep-alive
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.122 Safari/537.36
Accept: */*
Referer: http://118.190.217.8:3389/
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9</code></pre><p><strong>一个 HTTP 响应示例</strong>：</p><pre><code class="language-text">HTTP/1.1 200 OK
X-Powered-By: Express
Accept-Ranges: bytes
Cache-Control: public, max-age=0
Last-Modified: Sat, 07 Mar 2020 03:52:30 GMT
ETag: W/"253e-170b31f7de7"
Content-Type: application/javascript; charset=UTF-8
Vary: Accept-Encoding
Content-Encoding: gzip
Date: Fri, 15 May 2020 05:38:05 GMT
Connection: keep-alive
Transfer-Encoding: chunked</code></pre><h3 id="-">方法</h3><figure class="kg-card kg-image-card"><img src="https://pic1.zhimg.com/80/v2-1eff029d1e35612fb85ad1d6765d50c4_720w.jpg" class="kg-image" alt="v2-1eff029d1e35612fb85ad1d6765d50c4_720w" width="600" height="400" loading="lazy"></figure><h3 id="get-head">GET 和 HEAD</h3><p>其中 GET 和 HEAD 被称为安全方法，因为它们是幂等的（如果一个请求不管执行多少次，其结果都是一样的，这个请求就是<strong>幂等的</strong>），类似于 POST 就不是幂等的。</p><p>HEAD 方法和 GET 方法很类似，但服务器在响应中只返回首部。这就允许客户端在未获取实际资源的情况下，对资源的首部进行检查。使用 HEAD，可以：</p><ol><li>在不获取资源的情况下了解资源的情况。</li><li>通过查看响应状态码，看看某个对象是否存在。</li><li>通过查看首部，了解测试资源是否被修改了。</li></ol><p>服务器开发者必须确保返回的首部与 GET 请求所返回的首部完全相同。遵循 HTTP/1.1 规范，就必须实现 HEAD 方法。</p><h3 id="put">PUT</h3><p>与 GET 方法从服务器读取文档相反，PUT 方法会向服务器写入文档。PUT 方法的语义就是让服务器用请求的主体部分来创建一个由所请求的 URL 命名的新文档。 如果那个文档已存在，就覆盖它。</p><h3 id="post">POST</h3><p>POST 方法通常用来向服务器发送表单数据。</p><h3 id="trace">TRACE</h3><p>客户端发起一个请求时，这个请求可能要穿过路由器、防火墙、代理、网关等。每个中间节点都可能会修改原始的 HTTP 请求，TRACE 方法允许客户端在最终发起请求时，看看它变成了什么样子。</p><p>TRACE 请求会在目的服务器端发起一个“环回”诊断。行程最后一站的服务器会弹回一条 TRACE 响应，并在响应主体中携带它收到的原始请求报文。 这样客户端就可以查看在所有中间 HTTP 应用程序组成的请求/响应链上，原始报文是否被毁坏或修改过。<br></p><figure class="kg-card kg-image-card"><img src="https://pic3.zhimg.com/80/v2-f66c499fa15d2ae881c5aec8d3ee70be_720w.jpg" class="kg-image" alt="v2-f66c499fa15d2ae881c5aec8d3ee70be_720w" width="600" height="400" loading="lazy"></figure><p>TRACE 方法主要用于诊断，用于验证请求是否如愿穿过了请求/响应链。它也是一种工具，用来查看代理和其他应用程序对用户请求所产生的效果。 TRACE 请求中不能带有实体的主体部分。TRACE 响应的实体主体部分包含了响应服务器收到的请求的精确副本。</p><h3 id="options">OPTIONS</h3><p>OPTIONS 方法请求 Web 服务器告知其支持的各种功能。</p><h3 id="delete">DELETE</h3><p>DELETE 方法就是让服务器删除请求 URL 所指定的资源。</p><h3 id="--1">状态码</h3><figure class="kg-card kg-image-card"><img src="https://pic3.zhimg.com/80/v2-aff02263117f428811e86b71ad01ec7a_720w.jpg" class="kg-image" alt="v2-aff02263117f428811e86b71ad01ec7a_720w" width="600" height="400" loading="lazy"></figure><h3 id="300-399-">300~399 重定向状态码</h3><p>重定向状态码要么告诉客户端使用替代位置来访问他们感兴趣的资源，要么提供一个替代的响应而不是资源的内容。 如果资源已被移动，可以发送一个重定向状态码和一个可选的 Location 首部来告知客户端资源已被移走，以及现在在哪里可以找到它。这样，浏览器可以在不打扰使用者的情况下，透明地转入新的位置。</p><h3 id="400-499-">400~499 客户端错误状态码</h3><p>有时客户端会发送一些服务器无法处理的东西，例如格式错误的请求报文、一个不存在的 URL。</p><h3 id="500-599-">500~599 服务器错误状态码</h3><p>有时客户端发送了一条有效请求，服务器自身却出错了。</p><h3 id="--2">首部</h3><p>首部和方法共同配合工作，决定了客户端和服务器能做什么事情。</p><p><strong>首部分类</strong>：</p><ol><li>通用首部，可以出现在请求或响应报文中。</li><li>请求首部，提供更多有关请求的信息。</li><li>响应首部，提供更多有关响应的信息。</li><li>实体首部，描述主体的长度和内容，或者资源自身。</li><li>扩展首部，规范中没有定义的新首部。</li></ol><h3 id="--3">通用首部</h3><p>有些首部提供了与报文相关的最基本信息，它们被称为通用首部。以下是一些常见的通用首部：<br></p><figure class="kg-card kg-image-card"><img src="https://pic2.zhimg.com/80/v2-2f7b70e0538ccfed82cb4bea696b5f79_720w.jpg" class="kg-image" alt="v2-2f7b70e0538ccfed82cb4bea696b5f79_720w" width="600" height="400" loading="lazy"></figure><h3 id="--4"><br>请求首部</h3><p>请求首部是只在请求报文中有意义的首部，用于说明请求的详情。以下是一些常见的请求首部：</p><figure class="kg-card kg-image-card"><img src="https://pic1.zhimg.com/80/v2-bd43f3dbc08e9df61b77041526831854_720w.jpg" class="kg-image" alt="v2-bd43f3dbc08e9df61b77041526831854_720w" width="600" height="400" loading="lazy"></figure><h3 id="--5">响应首部</h3><p>响应首部让服务器为客户端提供了一些额外的信息。</p><h3 id="--6">实体首部</h3><p>实体首部提供了有关实体及其内容的大量信息，从有关对象类型的信息，到能够对资源使用的各种有效的请求方法。</p><p>例如<strong>内容首部</strong>，提供了与实体内容有关的特定信息，说明了其类型、尺寸以及处理它所需的其他有用信息。 另外，通用的缓存首部说明了如何或什么时候进行缓存。<strong>实体的缓存首部</strong>提供了与被缓存实体有关的信息。</p><figure class="kg-card kg-image-card"><img src="https://pic1.zhimg.com/80/v2-97b2ecf5532a21f520742cc0edb2f634_720w.jpg" class="kg-image" alt="v2-97b2ecf5532a21f520742cc0edb2f634_720w" width="600" height="400" loading="lazy"></figure><h3 id="--7">性能优化</h3><h3 id="1-http-">1. 减少 HTTP 请求</h3><p>每发起一个 HTTP 请求，都得经历三次握手建立 TCP 连接，如果连接只用来交换少量数据，这个过程就会严重降低 HTTP 性能。所以我们可以将多个小文件合成一个大文件，从而减少 HTTP 请求次数。</p><p>其实由于持久连接（重用 TCP 连接，以消除连接及关闭时延；HTTP/1.1 默认开启持久连接）的存在，每个新请求不一定都需要建立一个新的 TCP 连接。但是，浏览器处理完一个 HTTP 请求才能发起下一个，所以在 TCP 连接数没达到浏览器规定的上限时，还是会建立新的 TCP 连接。从这点来看，减少 HTTP 请求仍然是有必要的。</p><h3 id="2-cdn">2. 静态资源使用 CDN</h3><p>内容分发网络（CDN）是一组分布在多个不同地理位置的 Web 服务器。我们都知道，当服务器离用户越远时，延迟越高。CDN 就是为了解决这一问题，在多个位置部署服务器，让用户离服务器更近，从而缩短请求时间。</p><h3 id="3-">3. 善用缓存</h3><p>为了避免用户每次访问网站都得请求文件，我们可以通过添加 Expires 头来控制这一行为。Expires 设置了一个时间，只要在这个时间之前，浏览器都不会请求文件，而是直接使用缓存。</p><p>不过这样会产生一个问题，当文件更新了怎么办？怎么通知浏览器重新请求文件？</p><p>可以通过更新页面中引用的资源链接地址，让浏览器主动放弃缓存，加载新资源。</p><p>具体做法是把资源地址 URL 的修改与文件内容关联起来，也就是说，只有文件内容变化，才会导致相应 URL 的变更，从而实现文件级别的精确缓存控制。什么东西与文件内容相关呢？我们会很自然的联想到利用<a href="https://link.zhihu.com/?target=https%3A//baike.baidu.com/item/%25E6%25B6%2588%25E6%2581%25AF%25E6%2591%2598%25E8%25A6%2581%25E7%25AE%2597%25E6%25B3%2595/3286770%3Ffromtitle%3D%25E6%2591%2598%25E8%25A6%2581%25E7%25AE%2597%25E6%25B3%2595%26fromid%3D12011257" rel="nofollow noreferrer">数据摘要要算法</a>对文件求摘要信息，摘要信息与文件内容一一对应，就有了一种可以精确到单个文件粒度的缓存控制依据了。</p><p>参考资料：</p><ul><li><a href="https://www.zhihu.com/question/20790576/answer/32602154">张云龙--大公司里怎样开发和部署前端代码？</a></li></ul><h3 id="4-">4. 压缩文件</h3><p>压缩文件可以减少文件下载时间，让用户体验性更好。</p><p>gzip 是目前最流行和最有效的压缩方法。可以通过向 HTTP 请求头中的 Accept-Encoding 头添加 gzip 标识来开启这一功能。当然，服务器也得支持这一功能。</p><p>举个例子，我用 Vue 开发的项目构建后生成的 app.js 文件大小为 1.4MB，使用 gzip 压缩后只有 573KB，体积减少了将近 60%。</p><h3 id="5-max-age-no-cache-">5. 通过 max-age 和 no-cache 实现文件精确缓存</h3><p>通用消息头部 <code>Cache-Control</code> 其中有两个选项：</p><ol><li><code>max-age</code>: 设置缓存存储的最大周期，超过这个时间缓存被认为过期(单位秒)。在这个时间前，浏览器读取文件不会发出新请求，而是直接使用缓存。</li><li><code>no-cache</code>: 指定 no-cache 表示客户端可以缓存资源，每次使用缓存资源前都必须重新验证其有效性。</li></ol><p>我们可以将那些长期不变的静态资源设置一个非常长的缓存时间，例如设置成缓存一年。</p><p>然后将 <code>index.html</code> 文件设置成 <code>no-cache</code>。这样每次访问网站时，浏览器都会询问 <code>index.html</code> 是否有更新，如果没有，就使用旧的 <code>index.html</code> 文件。如果有更新，就读取新的 <code>index.html</code> 文件。当加载新的 <code>index.html</code> 时，也会去加载里面新的 URL 资源。</p><p>例如 <code>index.html</code> 原来引用了 <code>a.js</code> 和 <code>b.js</code>，现在更新了变成 <code>a.js</code> 和 <code>c.js</code>。那就只会加载 <code>c.js</code> 文件。</p><p>具体请看 <a href="https://link.zhihu.com/?target=https%3A//github.com/woai3c/node-blog/blob/master/doc/node-blog7.md" rel="nofollow noreferrer">webpack + express 实现文件精确缓存</a>。</p><h2 id="https">HTTPS</h2><p>HTTPS 是最流行的 HTTP 安全形式，由网景公司首创，所有主要的浏览器和服务器都支持此协议。 使用 HTTPS 时，所有的 HTTP 请求和响应数据在发送之前，都要进行加密。加密可以使用 SSL 或 TLS。</p><figure class="kg-card kg-image-card"><img src="https://pic4.zhimg.com/80/v2-bb65d4c1c08bffc3a1e10968e18911f7_720w.jpg" class="kg-image" alt="v2-bb65d4c1c08bffc3a1e10968e18911f7_720w" width="600" height="400" loading="lazy"></figure><p>SSL/TLS 协议作用在 HTTP 协议之下，对于上层应用来说，原来的发送/接收数据流程不变，这就很好地兼容了老的 HTTP 协议。由于 SSL/TLS 差别不大，下面统一使用 SSL。</p><p>要想了解 HTTPS 为何安全，还得继续了解一下这些概念：<strong>加密算法</strong>、<strong>摘要算法</strong>、<strong>数字签名</strong>和<strong>数字证书</strong>。</p><h3 id="--8">加密算法</h3><h3 id="--9">对称密钥密码体制</h3><p>对称密钥密码体制，即加密密钥和解密密钥是使用相同的密码体制。对称密钥加密技术的缺点之一就是发送者和接收者在对话之前，一定要有一个共享的密钥，所以不太安全。</p><h3 id="--10">公钥密码体制</h3><p>公钥密码体制使用不同的加密密钥与解密密钥。公钥密码体制产生的主要原因有两个：一是对称密钥密码体制的密钥分配问题，二是对数字签名的需求。</p><p>在公钥密码体制中，加密密钥是公开的，解密密钥是需要保密的，加密算法和解密算法也是公开的。</p><p>公钥密码体制的加密和解密有如下特点：</p><ol><li><strong>密钥对产生器</strong>产生出接收者 B 的一对密钥，即加密密钥 PK 和解密密钥 SK。</li><li>发送者 A 用 B 的公钥 PK 作为加密密钥来加密信息，B 接收后用解密密钥 SK 解密。</li></ol><figure class="kg-card kg-image-card"><img src="https://pic3.zhimg.com/80/v2-5ad7018640fb80e50e92d20484e81f86_720w.jpg" class="kg-image" alt="v2-5ad7018640fb80e50e92d20484e81f86_720w" width="600" height="400" loading="lazy"></figure><p>使用对称密钥时，由于双方使用同样的密钥，因此在通信信道上可以进行一对一的双向保密通信，双方都可以用同一个密钥加密解密。</p><p>使用公开密钥时，在通信信道上可以是多对一的单向保密信道。即可以有多人持有 B 的公钥，但只有 B 才能解密。</p><h3 id="--11">摘要算法</h3><p>摘要算法的主要特征是加密过程不需要密钥，并且经过加密的数据无法被解密，目前可以被解密逆向的只有CRC32算法，只有输入相同的明文数据经过相同的消息摘要算法才能得到相同的密文。</p><h3 id="--12">数字签名</h3><p>用加密系统对报文进行签名，以说明是谁编写的报文，同时证明报文未被篡改过，这种技术称为<strong>数字签名</strong>。</p><p>数字签名是附加在报文上的特殊加密校验码。使用数字签名的好处有：</p><ol><li>签名可以证明是作者编写了这条报文。只有作者才会有最机密的私有密钥，因此，只有作者才能计算出这些校验和。</li><li>签名可以防止报文被篡改，如果有人在报文传输过程中对其进行了修改，校验和就不再匹配了。</li></ol><p>数字签名通常是用非对称公开密钥技术产生的。</p><figure class="kg-card kg-image-card"><img src="https://pic1.zhimg.com/80/v2-dbe067a589d86e584a226ddd31c49f80_720w.jpg" class="kg-image" alt="v2-dbe067a589d86e584a226ddd31c49f80_720w" width="600" height="400" loading="lazy"></figure><p>看上图，任何人都能用 A 的公钥 PK 对密文进行 E 运算后得到 A 发送的明文。可见这种通信并非为了保密，而是为了进行签名和核实签名，即确认此信息是 A 发送的（使用 A 的密钥进行加密的报文，只有使用 A 的公钥才能正确解密）。 但上述过程仅对报文进行了签名，对报文 X 本身却未保密，所以要采用下图的方法，同时实现秘密通信和数字签名。</p><figure class="kg-card kg-image-card"><img src="https://pic4.zhimg.com/80/v2-113d720a3ca11d8d18ead0a54ac00e43_720w.jpg" class="kg-image" alt="v2-113d720a3ca11d8d18ead0a54ac00e43_720w" width="600" height="400" loading="lazy"></figure><h3 id="--13">数字证书</h3><p>假如你想访问一个网站，怎么确保对方给你的公钥是你想访问的网站的公钥，而不是被中间人篡改过的？</p><p>数字证书的出现就是为了解决这个问题，它是由数字证书认证机构颁发的，用来证明公钥拥有者的身份。换句话说，数字证书的作用就相当于人的身份证，身份证证明了张三就是张三，而不是别人。</p><p><strong>数字证书一般包含以下内容</strong>：</p><ol><li>对象的名称（人、服务器、组织等）；</li><li>过期时间；</li><li>证书发布者（由谁为证书担保）；</li><li>来自证书发布者的数字签名；</li><li>对象的公钥；</li><li>对象和所用签名算法的描述性信息。</li></ol><p>任何人都可以创建一个数字证书，但由谁来担保才是重点。</p><p><strong>数字证书的数字签名计算过程</strong>：</p><ol><li>用摘要算法对数字证书的内容计算出摘要；</li><li>用数字证书的私钥对摘要进行加密得到数字签名。</li></ol><figure class="kg-card kg-image-card"><img src="https://pic2.zhimg.com/80/v2-17ec75ef0f9ff1892eb6aada2c3d44e9_720w.jpg" class="kg-image" alt="v2-17ec75ef0f9ff1892eb6aada2c3d44e9_720w" width="600" height="400" loading="lazy"></figure><p>当浏览器收到证书时，会对签名颁发机构进行验证，如果颁发机构是个很有权威的公共签名机构，浏览器可能就知道其公开密钥了（浏览器会预装很多签名颁发机构的证书）。如果对签名颁发机构一无所知，浏览器通常会向用户显示一个对话框，看看他是否相信这个签名发布者。</p><p>因为数字证书的公钥是公开的，任何人都可以用公钥解密出数字证书的数字签名的摘要，然后再用同样的摘要算法对证书内容进行摘要计算，将得出的摘要和解密后的摘要作对比，如果内容一致则说明这个证书没有被篡改过，可以信任。</p><p>这个过程是建立在被大家所认可的证书机构之上得到的公钥，所以这是一种安全的方式。</p><figure class="kg-card kg-image-card"><img src="https://pic1.zhimg.com/80/v2-be99bd75b57e167a6dd28534c6070574_720w.jpg" class="kg-image" alt="v2-be99bd75b57e167a6dd28534c6070574_720w" width="600" height="400" loading="lazy"></figure><h3 id="https-">HTTPS 连接建立过程</h3><p>HTTPS 连接建立过程和 HTTP 差不多，区别在于 HTTP（默认端口 80） 请求只要在 TCP 连接建立后就可以发起，而 HTTPS（默认端口 443） 在 TCP 连接建立后，还需要经历 SSL 协议握手，成功后才能发起请求。</p><figure class="kg-card kg-image-card"><img src="https://pic2.zhimg.com/80/v2-ee3edd71c7aa0e6434f271aa71852335_720w.jpg" class="kg-image" alt="v2-ee3edd71c7aa0e6434f271aa71852335_720w" width="600" height="400" loading="lazy"></figure><figure class="kg-card kg-image-card"><img src="https://pic2.zhimg.com/80/v2-0adc50b67e0be922b2a9d6de861f1c95_720w.jpg" class="kg-image" alt="v2-0adc50b67e0be922b2a9d6de861f1c95_720w" width="600" height="400" loading="lazy"></figure><p>我知道肯定会有人不满足于简化版的 SSL 握手过程，所以我找了一篇文章<a href="https://link.zhihu.com/?target=https%3A//www.jianshu.com/p/7158568e4867" rel="nofollow noreferrer">SSL/TLS 握手过程详解</a>，这篇文章非常详细的讲解了 SSL 握手的每一步骤。建议有兴趣的同学看一看。</p><h2 id="http-2">HTTP/2</h2><p>HTTP/2 是 HTTP/1.x 的扩展，而非替代。所以 HTTP 的语义不变，提供的功能不变，HTTP 方法、状态码、URL 和首部字段等这些核心概念也不变。</p><p>之所以要递增一个大版本到 2.0，主要是因为它改变了客户端与服务器之间交换数据的方式。HTTP 2.0 增加了新的二进制分帧数据层，而这一层并不兼容之前的 HTTP 1.x 服务器及客户端——是谓 2.0。</p><h3 id="http-2-">HTTP/2 连接建立过程</h3><p>现在的主流浏览器 HTTP/2 的实现都是基于 SSL/TLS 的，也就是说使用 HTTP/2 的网站都是 HTTPS 协议的，所以本文只讨论基于 SSL/TLS 的 HTTP/2 连接建立过程。</p><p>基于 SSL/TLS 的 HTTP/2 连接建立过程和 HTTPS 差不多。在 SSL/TLS 握手协商过程中，客户端在 ClientHello 消息中设置 ALPN（应用层协议协商）扩展来表明期望使用 HTTP/2 协议，服务器用同样的方式回复。通过这种方式，HTTP/2 在 SSL/TLS 握手协商过程中就建立起来了。</p><h3 id="http-1-1-">HTTP/1.1 的问题</h3><h3 id="1-">1. 队头阻塞</h3><p>在 HTTP 请求应答过程中，如果出现了某种情况，导致响应一直未能完成，那后面所有的请求就会一直阻塞着，这种情况叫队头阻塞。</p><h3 id="2-tcp-">2. 低效的 TCP 利用</h3><p>由于 <a href="https://link.zhihu.com/?target=https%3A//baike.baidu.com/item/%25E6%2585%25A2%25E5%2590%25AF%25E5%258A%25A8/8242395" rel="nofollow noreferrer">TCP 慢启动机制</a>，导致每个 TCP 连接在一开始的时候传输速率都不高，在处理多个请求后，才会慢慢达到“合适”的速率。对于请求数据量很小的 HTTP 请求来说，这种情况就是种灾难。</p><h3 id="3--1">3. 臃肿的消息首部</h3><p>HTTP/1.1 的首部无法压缩，再加上 cookie 的存在，经常会出现首部大小比请求数据大小还大的情况。</p><h3 id="4--1">4. 受限的优先级设置</h3><p>HTTP/1.1 无法为重要的资源指定优先级，每个 HTTP 请求都是一视同仁。</p><p>在继续讨论 HTTP/2 的新功能之前，先把 HTTP/1.1 的问题列出来是有意义的。因为 HTTP/2 的某些新功能就是为了解决上述某些问题而产生的。</p><h3 id="--14">二进制分帧层</h3><p>HTTP/2 是基于帧的协议。采用分帧是为了将重要信息封装起来，让协议的解析方可以轻松阅读、解析并还原信息。</p><p>而 HTTP/1.1 是以文本分隔的。解析 HTTP/1.1 不需要什么高科技，但往往速度慢且容易出错。你需要不断地读入字节，直到遇到分隔符 CRLF 为止，同时还要考虑不守规矩的客户端，它只会发送 LF。</p><p>解析 HTTP/1.1 的请求或响应还会遇到以下问题：</p><ol><li>一次只能处理一个请求或响应，完成之前不能停止解析。</li><li>无法预判解析需要多少内存。</li></ol><p>HTTP/2 有了帧，处理协议的程序就能预先知道会收到什么，并且 HTTP/2 有表示帧长度的字段。</p><figure class="kg-card kg-image-card"><img src="https://pic2.zhimg.com/80/v2-b5e21a1d51a86e69835cf4fc2b0ead6d_720w.jpg" class="kg-image" alt="v2-b5e21a1d51a86e69835cf4fc2b0ead6d_720w" width="600" height="400" loading="lazy"></figure><h3 id="--15">帧结构</h3><pre><code class="language-text">+-----------------------------------------------+
 |                 Length (24)                   |
 +---------------+---------------+---------------+
 |   Type (8)    |   Flags (8)   |
 +-+-------------+---------------+-------------------------------+
 |R|                 Stream Identifier (31)                      |
 +=+=============================================================+
 |                   Frame Payload (0...)                      ...
 +---------------------------------------------------------------+</code></pre><figure class="kg-card kg-image-card"><img src="https://pic4.zhimg.com/80/v2-7f7d60db1b3a2d3ff25b613a4cbeaa97_720w.jpg" class="kg-image" alt="v2-7f7d60db1b3a2d3ff25b613a4cbeaa97_720w" width="600" height="400" loading="lazy"></figure><p>由于 HTTP/2 是分帧的，请求和响应都可以多路复用，有助于解决类似类似队头阻塞的问题。</p><h3 id="--16">帧类型</h3><figure class="kg-card kg-image-card"><img src="https://pic2.zhimg.com/80/v2-de35fa232ac8c4b181ede6f7af13925d_720w.jpg" class="kg-image" alt="v2-de35fa232ac8c4b181ede6f7af13925d_720w" width="600" height="400" loading="lazy"></figure><h3 id="--17">多路复用</h3><p>在 HTTP/1.1 中，如果客户端想发送多个并行的请求，那么必须使用多个 TCP 连接。</p><p>而 HTTP/2 的二进制分帧层突破了这一限制，所有的请求和响应都在同一个 TCP 连接上发送：客户端和服务器把 HTTP 消息分解成多个帧，然后乱序发送，最后在另一端再根据流 ID 重新组合起来。</p><p>这个机制为 HTTP 带来了巨大的性能提升，因为：</p><ul><li>可以并行交错地发送请求，请求之间互不影响；</li><li>可以并行交错地发送响应，响应之间互不干扰；</li><li>只使用一个连接即可并行发送多个请求和响应；</li><li>消除不必要的延迟，从而减少页面加载的时间；</li><li>不必再为绕过 HTTP 1.x 限制而多做很多工作；</li></ul><figure class="kg-card kg-image-card"><img src="https://pic2.zhimg.com/80/v2-369330c2d4712cb12cdb7124ec691931_720w.jpg" class="kg-image" alt="v2-369330c2d4712cb12cdb7124ec691931_720w" width="600" height="400" loading="lazy"></figure><h3 id="--18">流</h3><p>HTTP/2 规范对流的定义是：HTTP/2 连接上独立的、双向的帧序列交换。如果客户端想要发出请求，它会开启一个新流，然后服务器在这个流上回复。 由于有分帧，所以多个请求和响应可以交错，而不会互相阻塞。流 ID 用来标识帧所属的流。</p><p>客户端到服务器的 HTTP/2 连接建立后，通过发送 HEADERS 帧来启动新的流。如果首部需要跨多个帧，可能还会发送 CONTINUATION 帧。该 HEADERS 帧可能来自请求或响应。 后续流启动的时候，会发送一个带有递增流 ID 的新 HEADERS 帧。</p><h3 id="--19">消息</h3><p>HTTP 消息泛指 HTTP 请求或响应，消息由一或多个帧组成，这些帧可以乱序发送，然后再根据每个帧首部的流 ID 重新组装。</p><p>一个消息至少由 HEADERS 帧（它初始化流）组成，并且可以另外包含 CONTINUATION 和 DATA 帧，以及其他的 HEADERS 帧。</p><figure class="kg-card kg-image-card"><img src="https://pic3.zhimg.com/80/v2-b42c13b2eb2f9e68fa6c525b0c2ec1ba_720w.jpg" class="kg-image" alt="v2-b42c13b2eb2f9e68fa6c525b0c2ec1ba_720w" width="600" height="400" loading="lazy"></figure><p>HTTP/1.1 的请求和响应部分都分成消息首部和消息体两部分；HTTP/2 的请求和响应分成 HEADERS 帧和 DATA 帧。</p><h3 id="--20">优先级</h3><p>把 HTTP 消息分解为很多独立的帧之后，就可以通过优化这些帧的交错和传输顺序，进一步提升性能。</p><p>通过 HEADERS 帧和 PRIORITY 帧，客户端可以明确地和服务器沟通它需要什么，以及它需要这些资源的顺序。具体来讲，服务器可以根据流的优先级，控制资源分配（CPU、内存、带宽），而在响应数据准备好之后，优先将最高优先级的帧发送给客户端。</p><h3 id="--21">流量控制</h3><p>在同一个 TCP 连接上传输多个数据流，就意味着要共享带宽。标定数据流的优先级有助于按序交付，但只有优先级还不足以确定多个数据流或多个连接间的资源分配。</p><p>为解决这个问题，HTTP/2 为数据流和连接的流量控制提供了一个简单的机制：</p><ul><li>流量控制基于每一跳进行，而非端到端的控制；</li><li>流量控制基于 WINDOW_UPDATE 帧进行，即接收方广播自己准备接收某个数据流的多少字节，以及对整个连接要接收多少字节；</li><li>流量控制窗口大小通过 WINDOW_UPDATE 帧更新，这个字段指定了流 ID 和窗口大小递增值；</li><li>流量控制有方向性，即接收方可能根据自己的情况为每个流乃至整个连接设置任意窗口大小；</li><li>流量控制可以由接收方禁用，包括针对个别的流和针对整个连接。</li></ul><p>HTTP/2 连接建立之后，客户端与服务器交换 SETTINGS 帧，目的是设置双向的流量控制窗口大小。除此之外，任何一端都可以选择禁用个别流或整个连接的流量控制。</p><h3 id="--22">服务器推送</h3><p>HTTP/2 新增的一个强大的新功能，就是服务器可以对一个客户端请求发送多个响应。换句话说，除了对最初请求的响应外，服务器还可以额外向客户端推送资源，而无需客户端明确地请求。</p><figure class="kg-card kg-image-card"><img src="https://pic3.zhimg.com/80/v2-d4e4f7bbaa1d8d2707951dfa993291e2_720w.jpg" class="kg-image" alt="v2-d4e4f7bbaa1d8d2707951dfa993291e2_720w" width="600" height="400" loading="lazy"></figure><p>为什么需要这样一个机制呢？通常的 Web 应用都由几十个资源组成，客户端需要分析服务器提供的文档才能逐个找到它们。那为什么不让服务器提前就把这些资源推送给客户端，从而减少额外的时间延迟呢？服务器已经知道客户端下一步要请求什么资源了，这时候服务器推送即可派上用场。</p><p>另外，客户端也可以拒绝服务器的推送。</p><h3 id="--23">首部压缩</h3><p>HTTP/1.1 存在的一个问题就是臃肿的首部，HTTP/2 对这一问题进行了改进，可以对首部进行压缩。 在一个 Web 页面中，一般都会包含大量的请求，而其中有很多请求的首部往往有很多重复的部分。</p><p>例如有如下两个请求：</p><pre><code class="language-text">:authority: unpkg.zhimg.com
:method: GET
:path: /za-js-sdk@2.16.0/dist/zap.js
:scheme: https
accept: */*
accept-encoding: gzip, deflate, br
accept-language: zh-CN,zh;q=0.9
cache-control: no-cache
pragma: no-cache
referer: https://www.zhihu.com/
sec-fetch-dest: script
sec-fetch-mode: no-cors
sec-fetch-site: cross-site
user-agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.122 Safari/537.36</code></pre><pre><code class="language-http">:authority: zz.bdstatic.com
:method: GET
:path: /linksubmit/push.js
:scheme: https
accept: */*
accept-encoding: gzip, deflate, br
accept-language: zh-CN,zh;q=0.9
cache-control: no-cache
pragma: no-cache
referer: https://www.zhihu.com/
sec-fetch-dest: script
sec-fetch-mode: no-cors
sec-fetch-site: cross-site
user-agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.122 Safari/537.36</code></pre><p>从上面两个请求可以看出来，有很多数据都是重复的。如果可以把相同的首部存储起来，仅发送它们之间不同的部分，就可以节省不少的流量，加快请求的时间。</p><p>HTTP/2 在客户端和服务器端使用“首部表”来跟踪和存储之前发送的键－值对，对于相同的数据，不再通过每次请求和响应发送。</p><p>下面再来看一个简化的例子，假设客户端按顺序发送如下请求首部：</p><pre><code class="language-text">Header1:foo
Header2:bar
Header3:bat</code></pre><p>当客户端发送请求时，它会根据首部值创建一张表：</p><figure class="kg-card kg-image-card"><img src="https://pic3.zhimg.com/80/v2-50b11e7a83b07c281fcfb483c576f542_720w.jpg" class="kg-image" alt="v2-50b11e7a83b07c281fcfb483c576f542_720w" width="600" height="400" loading="lazy"></figure><p>如果服务器收到了请求，它会照样创建一张表。 当客户端发送下一个请求的时候，如果首部相同，它可以直接发送这样的首部块：</p><pre><code class="language-text">62 63 64</code></pre><p>服务器会查找先前建立的表格，并把这些数字还原成索引对应的完整首部。</p><h3 id="--24">性能优化</h3><p>使用 HTTP/2 代替 HTTP/1.1，本身就是一种巨大的性能提升。 这小节要聊的是在 HTTP/1.1 中的某些优化手段，在 HTTP/2 中是不必要的，可以取消的。</p><h3 id="--25">取消合并资源</h3><p>在 HTTP/1.1 中要把多个小资源合并成一个大资源，从而减少请求。而在 HTTP/2 就不需要了，因为 HTTP/2 所有的请求都可以在一个 TCP 连接发送。</p><h3 id="--26">取消域名拆分</h3><p>取消域名拆分的理由同上，再多的 HTTP 请求都可以在一个 TCP 连接上发送，所以不需要采取多个域名来突破浏览器 TCP 连接数限制这一规则了。</p><h2 id="--27">参考资料</h2><ul><li><a href="https://link.zhihu.com/?target=https%3A//book.douban.com/subject/10746113/" rel="nofollow noreferrer">HTTP权威指南</a></li><li><a href="https://link.zhihu.com/?target=https%3A//book.douban.com/subject/27665112/" rel="nofollow noreferrer">HTTP/2基础教程</a></li><li><a href="https://link.zhihu.com/?target=https%3A//www.jianshu.com/p/7158568e4867" rel="nofollow noreferrer">SSL/TLS 握手过程详解</a></li><li><a href="https://link.zhihu.com/?target=https%3A//www.jianshu.com/p/ffe8c203a471" rel="nofollow noreferrer">互联网安全之数字签名、数字证书与PKI系统</a></li><li><a href="https://link.zhihu.com/?target=https%3A//book.douban.com/subject/26960678/" rel="nofollow noreferrer">计算机网络（第7版）</a></li><li><a href="https://link.zhihu.com/?target=https%3A//book.douban.com/subject/25856314/" rel="nofollow noreferrer">Web性能权威指南</a></li></ul><h3 id="--28"><a href="https://www.zhihu.com/people/tan-guang-zhi-19/posts">更多文章，敬请关注</a></h3> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ TCP vs UDP——哪个协议更快？ ]]>
                </title>
                <description>
                    <![CDATA[ 什么是 TCP？ TCP  是 Transmission Control Protocol  的首字母缩写词，它是一种传输层协议，允许数据包从一个位置发送到另一个位置。 TCP 是面向连接的协议，也就是说它在网络计算机单元之间的任何通信之前建立连接。由于我们把这个协议与 IP 协议结合使用，我们称其为 TCP/IP。 TCP 是怎么工作的? TCP 的主要任务是从应用层收集数据。它将数据拆分成多个数据包，为每个数据包分配一个编号，然后将这些数据包发送到它们的目的地。 同样，在将数据包发送到应用层之前，它会重新组合数据包。鉴于 TCP 是面向连接的协议，这个连接将一直保持，直到发送方和接收方完成数据交换。 它是一种可靠的协议。因为，接收方总是会给发送方提供一条关于数据包的确认消息，要么肯定要么否定，因此，发送方总是能知道数据包是否到达它的目的地，还是说需要被重新发送。 它保证了数据能到达其目的地，而且到达的顺序与发送时相同。它有一套内置的错误检查和恢复体系，负责提供端到端通信。TCP 还提供对流量控制和服务质量的访问。 TCP 支持全双工服务器，既可以当接收者，也可以当发送者 ]]>
                </description>
                <link>https://www.freecodecamp.org/chinese/news/tcp-vs-udp-which-is-faster/</link>
                <guid isPermaLink="false">60dbf2ad240b4e0653a3e18e</guid>
                
                    <category>
                        <![CDATA[ 计算机网络 ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Sean Bei ]]>
                </dc:creator>
                <pubDate>Wed, 30 Jun 2021 04:30:05 +0000</pubDate>
                <media:content url="https://chinese.freecodecamp.org/news/content/images/2021/06/TCP-VS-UDP.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <h2 id="tcp">什么是 TCP？</h2>
<p><strong>TCP</strong> 是 <strong>Transmission Control Protocol</strong> 的首字母缩写词，它是一种传输层协议，<strong>允许数据包</strong>从一个位置发送到另一个位置。</p>
<p>TCP 是面向连接的协议，也就是说它在网络计算机单元之间的任何通信之前建立连接。由于我们把这个协议与 IP 协议结合使用，我们称其为 <strong>TCP/IP</strong>。</p>
<h3 id="tcp">TCP 是怎么工作的?</h3>
<p>TCP 的主要任务是从应用层收集数据。它将数据拆分成多个数据包，为每个数据包分配一个编号，然后将这些数据包发送到它们的目的地。</p>
<p>同样，在将数据包发送到应用层之前，它会重新组合数据包。鉴于 TCP 是面向连接的协议，这个连接将一直保持，直到发送方和接收方完成数据交换。</p>
<p>它是一种可靠的协议。因为，接收方总是会给发送方提供一条关于数据包的确认消息，要么肯定要么否定，因此，发送方总是能知道数据包是否到达它的目的地，还是说需要被重新发送。</p>
<p>它保证了数据能到达其目的地，而且到达的顺序与发送时相同。它有一套内置的错误检查和恢复体系，负责提供端到端通信。TCP 还提供对流量控制和服务质量的访问。</p>
<p>TCP 支持<strong>全双工服务器</strong>，既可以当接收者，也可以当发送者。它以点对点的客户端/服务器方式运行。</p>
<h2 id="udp">什么是 UDP？</h2>
<p><strong>UDP</strong> 是 <strong>User Datagram Protocol</strong> 的首字母缩写词。用户数据报协议（UDP）是 TCP/IP 协议套件的最基本的传输层通信协议。它使用最低限度的通信机制。</p>
<h3 id="udp">UDP 是怎么工作的？</h3>
<p>尽管 UDP 被认为是一种不可靠的传输协议，但它通过使用 IP 服务来完成其工作，提供了一种尽力而为的传递方法。</p>
<p>在 UDP 中，接收方不生成数据包的确认，发送方也不等待数据包的确认。正是这个不足，使得该协议虽不可靠但是易于处理。</p>
<p>如果确认是否接收到数据这点并不那么重要，这种情况下，我们使用 UDP。它很适用于单向数据流的场景，最适合基于查询的通信。</p>
<p>UDP 不保证数据包的有序传递。它是无状态的，不提供任何拥塞控制机制。</p>
<figure class="kg-card kg-card-image kg-card-hascaption">
    <img src="https://www.freecodecamp.org/news/content/images/2021/05/Screenshot-2021-05-31-at-10.54.01-AM.png" alt="TCP 与 UDP" class="kg-image" width="600" height="400" loading="lazy">
    <figcaption>TCP 与 UDP</figcaption>
</figure>
<h2 id="tcpudp">TCP 与 UDP 的区别</h2>
<p>UDP 是一种无连接协议，而 TCP 是一种面向连接的协议。TCP 比 UDP 要慢，这是两种协议的主要区别之一。</p>
<p>总的来说，UDP 是一种更快、更简单、更高效的协议。但是只有 TCP 允许对丢失的数据包进行重新传输。</p>
<p>TCP 和 UDP 的另一个区别是 TCP 可以确保数据从用户到服务器的有序传输（反之亦然）。UDP 不是为端到端通信而设计的，并不会检查接收方的准备情况，因此它需要相对更少的开销并占用更少的空间。</p>
<h3 id="tcpudp">TCP 与 UDP 的总结</h3>
<h4 id="">连接</h4>
<p>TCP 要求在发送方和接收方开始通信之前建立一个良好的连接，它是一个面向连接的协议。</p>
<p>UDP 是一种无连接协议。</p>
<h4 id="">保持数据传输的顺序</h4>
<p>在 TCP 中，由于事先建立了一个良好的连接，接收方以有序的方式接收数据包。</p>
<p>而在 UDP 中，发送方与接收方之间并没有建立良好的连接，接收方将以无序的方式接收数据包。</p>
<h4 id="">可靠性</h4>
<p>每当通过 TCP 接收到数据包时，接收方都会向发送方发送一条确认。万一失败，它会请求重新传输。</p>
<p>而使用 UDP，在这种情况下不会发送确认，它依赖于高层协议来确保可靠性。</p>
<h4 id="">错误检查</h4>
<p>TCP 中有广泛的错误检查规则，而 UDP 中只有基本的错误检查技术，例如校验和。</p>
<h4 id="">传输方法</h4>
<p>在 TCP 中，数据以字节流的形式读取，消息被发送到段边界。</p>
<p>而在 UDP 中，已定义限制的单个 UDP 数据包被发送，在到达接收方时验证其完整性。</p>
<h4 id="">广播</h4>
<p>TCP 不支持广播。当你使用它时，发送方和接收方必须先建立一条连接，在传输结束后又必须终止这条连接。</p>
<p>UDP 支持广播。</p>
<h3 id="tcpudp">TCP 与 UDP 的用例</h3>
<p>TCP 被用于 HTTPS（安全超文本传输协议）、HTTP（超文本传输协议）、SMTP（简单邮件传输协议）、FTP（文件传输协议）等等。</p>
<p>UDP 用于视频流、视频电话、IP 语音服务（互联网呼叫）、DNS（域名系统）等。</p>
<h2 id="tcpudp">TCP 对比 UDP - 哪个更快?</h2>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/05/Screenshot-2021-05-31-at-10.55.58-AM.png" alt="Screenshot-2021-05-31-at-10.55.58-AM" width="600" height="400" loading="lazy"></p>
<p>通常来说，UDP 比 TCP 更快，原因如下：</p>
<h3 id="tcpudp">TCP 与 UDP 报头大小的差异</h3>
<p>让我们来分析看看 TCP 数据包和 UDP 数据包各自的报头。</p>
<p>TCP 报头的长度必须至少为 20 字节且不超过 60 字节。</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/05/Screenshot-2021-05-31-at-10.56.59-AM.png" alt="Screenshot-2021-05-31-at-10.56.59-AM" width="600" height="400" loading="lazy"></p>
<h4 id="tcp">TCP 的报头包括：</h4>
<ol>
<li><strong>源端口</strong> - 表示发送设备的源端口。占 16 位。</li>
<li><strong>目的端口</strong> - 表示接收设备上的目的端口。占 16 位。</li>
<li><strong>序号</strong> - 表示在一个会话中数据段的序号。占 32 位。</li>
<li><strong>确认号</strong> - 该编号包括下一个预期的数据字节的序号，并在 ACK 标志被设置时，用作对先前接收到的数据的确认。占 32 位。</li>
<li><strong>数据偏移</strong> - 该字段表示整个 TCP 报头的大小（32 位字）以及当前数据包在整个 TCP 段上的数据偏移量。占 4 位。</li>
<li><strong>保留</strong> -  供将来使用的位，默认情况下设置为 0。占 3 位。</li>
<li><strong>标志</strong> - 为各种标志保留了 1 位，这些标志有助于 TCP 检查各种活动，例如确认。</li>
<li><strong>校验和</strong> - 该字段包含校验和。</li>
<li><strong>紧急指针</strong> - 如果 URG 标志设置为 1，则指定数据字节。</li>
<li><strong>选项</strong> - 指定了在常规报头中不存在的其他选项。</li>
</ol>
<p>现在让我们来分析一个 UDP 报头。</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/05/Screenshot-2021-05-31-at-10.57.27-AM.png" alt="Screenshot-2021-05-31-at-10.57.27-AM" width="600" height="400" loading="lazy"></p>
<h4 id="udp">UDP 的报头包括：</h4>
<ol>
<li><strong>源端口</strong> - 表示发送设备的源端口。占 16 位。</li>
<li><strong>目的端口</strong> - 表示接收设备上的目的端口。占 16 位。</li>
<li><strong>长度</strong> - 指定 UDP 数据包的整体长度。它是一个 16 位的字段，最小值为 8 字节，等于 UDP 报头本身的大小。</li>
<li><strong>校验和</strong> - 发送方在发送之前创建的校验和存储在此字段中。该字段在 IPv4 中是可选的，因此如果它不包含任何值，则设置为 0，并且其所有位都设置为 0。</li>
</ol>
<p>我们可以清楚地看到 TCP 报头与 UDP 报头的开销差异。由于 TCP 报头比 UDP 报头大很多, 它需要更多的时间来处理，这使得了 UDP 比 TCP 更快。</p>
<h3 id="tcpudp">TCP 与 UDP 中的确认</h3>
<p>在 TCP 中，接收方在接收到的数据段上向发送方发送确认。这确保了数据包已传送到接收方。</p>
<p>如果没有收到确认，发送方会尝试重新传输。这个处理过程使得 TCP 比 UDP 慢得多。别忘了，UDP 不发送任何确认。</p>
<h3 id="">规则的例外</h3>
<p>在某些情况下，TCP 被证实比 UDP 要快。例如，在一个实验中，在一个最大传输单元为 1500 字节的以太网连接上，发送 300 字节的数据包，TCP 比 UDP 大约快 50%。</p>
<p>这是因为 TCP 会尝试缓存数据，填充到整个网段，从而最大化利用了带宽。而另一边，UDP 立即沿线路发送数据包，这些小数据包很多，堵塞了网络。</p>
<h2 id="">结论</h2>
<p>TCP 和 UDP 都有各自的用途。如果主要关注数据接收的可靠性和顺序，你会更希望使用 TCP。</p>
<p>另一方面，如果主要关注的是速度，而且某些数据包的受损或丢失并不那么重要，请选择 UDP。</p>
<p>所以可以看到，你不得不在可靠性和速度这两个之间进行妥协。如果提升其中一个，由于前面的限制，另一个会下降。</p>
<p>例如，在 YouTube 视频中，您可能已经注意到，有多种选项用于设置视频的质量。</p>
<p>当提高质量时，视频会占用更多带宽。这是因为画质较低时，即使某些数据包丢失，我们也会忽略它们。但是如果想要高质量的视频，我们便不能丢失数据包。</p>
<p>感谢阅读！希望你对 TCP 与 UDP 有了一个更好的了解。</p>
<!--kg-card-end: markdown--><p>原文：<a href="https://www.freecodecamp.org/news/tcp-vs-udp-which-is-faster/">TCP vs UDP – Which Protocol is Faster?</a>，作者：<a href="https://www.freecodecamp.org/news/author/prashanth/">Prashanth</a></p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ 白话 OSI 七层网络模型 ]]>
                </title>
                <description>
                    <![CDATA[ 本文讲的是开放网络互联（OSI，Open Systems Interconnection）模型以及网络体系结构中的七个层次。 OSI 模型是一个描述网络功能的概念框架。简单来说，OSI 模型标对计算机系统彼此之间发送信息的方式进行了标准化。 学习网络有点像学习一门语言——有很多标准，又有一些例外。因此，真正理解 “OSI 模型不是一组规则”非常重要，它是一个用于理解网络如何运作的工具。 当你学会了 OSI 模型，你不仅能进一步理解和欣赏这个被我们称之为“因特网”的宏大实体，还能更轻松流畅地排查网络问题。 向因特网致敬！ 预备知识 虽然你无需具备任何编程或网络方面的经验就能理解本文，但是你需要：  * 基本熟悉常见的网络术语（下面会解释）  * 好奇事物如何运作的 :) 学习目标 你将从本文学到：  1. 什么是 OSI 模型  2. 七层模型中各层的用途  3. 七层模型中各层可能出现的问题  4. TCP/IP 模型与 OSI 模型的区别 常见网络术语 这里是一些常见的网络术语，为了充分理解本文，你应该熟悉它们。我会在接下来谈论 OSI 各层的时候使用这些术语。  ]]>
                </description>
                <link>https://www.freecodecamp.org/chinese/news/osi-model-networking-layers/</link>
                <guid isPermaLink="false">6018bbbf6183a7054015635e</guid>
                
                    <category>
                        <![CDATA[ 计算机网络 ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Nicholas Zhan ]]>
                </dc:creator>
                <pubDate>Tue, 02 Feb 2021 02:30:00 +0000</pubDate>
                <media:content url="https://chinese.freecodecamp.org/news/content/images/2021/02/network-3537401_1920.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>本文讲的是开放网络互联（OSI，Open Systems Interconnection）模型以及网络体系结构中的七个层次。</p>
<p>OSI 模型是一个描述网络功能的概念框架。简单来说，OSI 模型标对计算机系统彼此之间发送信息的方式进行了标准化。</p>
<p>学习网络有点像学习一门语言——有很多标准，又有一些例外。因此，真正理解 “OSI 模型不是一组规则”非常重要，它是一个用于理解网络如何运作的工具。</p>
<p>当你学会了 OSI 模型，你不仅能进一步理解和欣赏这个被我们称之为“因特网”的宏大实体，还能更轻松流畅地排查网络问题。</p>
<p>向因特网致敬！</p>
<h2 id="">预备知识</h2>
<p>虽然你无需具备任何编程或网络方面的经验就能理解本文，但是你需要：</p>
<ul>
<li>基本熟悉常见的网络术语（下面会解释）</li>
<li>好奇事物如何运作的 :)</li>
</ul>
<h2 id="">学习目标</h2>
<p>你将从本文学到：</p>
<ol>
<li>什么是 OSI 模型</li>
<li>七层模型中各层的用途</li>
<li>七层模型中各层可能出现的问题</li>
<li>TCP/IP 模型与 OSI 模型的区别</li>
</ol>
<h2 id="">常见网络术语</h2>
<p>这里是一些常见的网络术语，为了充分理解本文，你应该熟悉它们。我会在接下来谈论 OSI 各层的时候使用这些术语。</p>
<h3 id="">节点</h3>
<p>节点（node）是连接到网络的物理电子设备，比如电脑、打印机、路由器等等。如果配置正确的话，节点可以在网络上进行信息的收发。</p>
<p>节点可以彼此相邻，其中的节点 A 可以直接连接到节点 B。节点之间也可以有中间节点，例如节点 A 和节点 B 之间可以放置一个交换机或路由器。</p>
<p>通常，路由器将网络连接到因特网，而交换机运行在网络内部，促进内网通信。<a href="https://www.themillergroup.com/differences-hubs-switches-routers/">了解更多有关集线器、交换机和路由器的信息</a>。</p>
<p>举个例子：</p>
<figure>
    <img src="https://chinese.freecodecamp.org/news/content/images/2021/11/1-Router-Image.jpeg" width="600" height="400" alt="1-Router-Image" loading="lazy">
    <figcaption><a href="https://learning.oreilly.com/library/view/the-illustrated-network/9780128110287/xhtml/chp001.xhtml">来源</a></figcaption>
</figure>
<p><em>对于我们当中那些挑剔的人来说（没错，我发现你了），<strong>主机（host）</strong> 将是你在网络中遇到的另一个术语。我将把它定义为一种需要具有 IP 地址的节点。所有的主机都是节点，但是并不是所有的节点都是主机。如果你不赞同，带着愤怒 Tweet 我吧。</em></p>
<h3 id="">链路</h3>
<p>链路（link）连接网络中的节点，它可以是有线的，比如以太网，也可以是无线的，比如 WiFi。</p>
<p>链路要么是点对点的（节点 A 与节点 B 相连），要么是多点的（节点 A 与节点 B 和节点 C 相连）。</p>
<p>我们也可以在谈论信息传输时将其描述成一对一与一对多的关系。</p>
<h3 id="">协议</h3>
<p>协议（protocol）是一组相互商定的规则，允许网络中的两个节点交换数据。</p>
<blockquote>
<p>“协议定义了管理通信过程中语法（可通信的内容）、语义（如何通信）以及同步（何时通信以及通信的速度）的规则。协议可以由硬件、软件或二者的组合实现。协议可以由任何人创建，但是最被广泛采纳的协议都是基于标准的。” —— The Illustrated Network</p>
</blockquote>
<p>有线和无线链路都可以有协议。</p>
<p>虽然任何人都可以创建协议，但是基于因特网组织（例如，因特网工程任务组（IETF，Internet Engineering Task Force））发布的标准的协议通常是最被广泛采纳的。</p>
<h3 id="">网络</h3>
<p>网络（network）是一组计算机、打印机或任何其它想要共享数据的设备的通用术语。</p>
<p>网络的类型包括：LAN、HAN、CAN、MAN、WAN、BAN 或 VPN。你觉得我只是随便用 <em>can</em> 一词来押韵吗？才不是呢——这些都是真实的网络类型。从<a href="https://www.c1c.net/blog/network-101/">这里</a>了解更多。</p>
<h3 id="">拓扑</h3>
<p>拓扑（topology）描述的是节点和链路如何在网络配置中组合在一起，通常用图描述。这里是一些常见的网络拓扑类型：</p>
<figure>
    <img src="https://chinese.freecodecamp.org/news/content/images/2021/11/2-Network-Topology-Types.png" alt="What is Network Topology? Best Guide to Types &amp; Diagrams - DNSstuff" width="600" height="400" loading="lazy">
    <figcaption><a href="https://www.dnsstuff.com/what-is-network-topology">来源</a> + <a href="https://www.geeksforgeeks.org/types-of-network-topology/">了解更多网络拓扑</a></figcaption>
</figure>
<p><em>网络由节点、节点之间的链路和管理节点间数据传输的协议组成。</em></p>
<p>无论网络的规模和复杂度如何，你都可以通过学习 OSI 模型和七层网络来理解所有在计算机网络中发生的事情。</p>
<h1 id="osi">什么是 OSI 模型？</h1>
<p>OSI 模型由七层网络组成。</p>
<p>首先，层（layer）是什么？</p>
<figure>
    <img src="https://chinese.freecodecamp.org/news/content/images/2021/11/3-Dragon-Lair.jpeg" alt="洞穴、龙穴、群山" width="600" height="400" loading="lazy">
    <figcaption><a href="https://pixabay.com/photos/cave-dragon-s-lair-mountains-1766835/">来源</a></figcaption>
</figure>
<p>噢，巢穴（lair）。</p>
<p>不，层——而不是 <em>巢穴</em>。这里没有龙。</p>
<p><em>层是对网络上的功能和行为进行分类和分组的一种方式。</em></p>
<p>在 OSI 模型中，层的组织结构从最具形态和最物理到不太有形，虚拟但更接近最终用户。</p>
<p>每一层都 <em>抽象</em> 低层的功能，直到最高层为止。最终用户是看不到所有其它层的所有细节和内部运作的。</p>
<p>如何记住所有层的名字呢？很简单。</p>
<blockquote>
<p>请不要把暗号告诉任何人（Please Do Not Tell the Secret Password to Anyone）。</p>
</blockquote>
<ul>
<li><strong>Please</strong> | 物理层（Physical Layer）</li>
<li><strong>Do</strong> | 数据链路层（Data Link Layer）</li>
<li><strong>Not</strong> | 网络层（Network Layer）</li>
<li><strong>Tell</strong> （the）| 传输层（Transport Layer）</li>
<li><strong>Secret</strong> | 会话层（Session Layer）</li>
<li><strong>Password</strong> （to）| 表示层（Presentation Layer）</li>
<li><strong>Anyone</strong> | 应用层（Application Layer）</li>
</ul>
<p><em>要牢记：虽然某些技术（比如协议）在逻辑上比起其它层来说可能“属于”某一层，但并非所有的技术都完全契合 OSI 模型中的单个层。例如，以太网（Ethernet）、802.11（Wifi）和地址解析协议（ARP，Address Resolution Protocol）程序在不只一层上工作。</em></p>
<p>OSI 只是一个模型，一个工具，并不是一组规则。</p>
<h2 id="osi">OSI 第一层</h2>
<p>第一层是 <strong>物理层</strong>。第一层中有很多技术——从物理网络设备、布线到电缆如何连接到设备之间的一切。另外，如果我们不需要电缆，那么信号的类型和传输方式是什么（例如，无线宽带）。</p>
<p>我没有列出第一层中的各种技术，而是为这些技术创建了一个更大的分类。我鼓励读者进一步学习每一种分类：</p>
<ul>
<li><strong>节点（设备）和网络硬件。</strong> 设备包括集线器、中继器、路由器、计算机、打印机，等等。这些设备内的硬件包括天线、放大器、网卡（NIC，Network Interface Card），等等。</li>
<li><strong>设备接口机制。</strong> 电缆如何连接到某个设备，以及连接到设备上的哪个地方（电缆连接器和设备插座）？连接器的大小和形状如何，它有多少个引脚？决定引脚处于活动状态还是非活动状态的东西是什么？</li>
<li><strong>功能和程序逻辑。</strong> 连接器中每个引脚的功能是什么——发送还是接收？决定事件顺序，以便节点能够开始与第二层上的另一个节点通信的程序逻辑是什么？</li>
<li><strong>电缆协议和规范。</strong> 以太网（CAT）、USB、<a href="https://www.centurylink.com/home/help/internet/what-is-DSL.html">数字用户线（DSL，Digital Subcriber Line）</a>等。规范包括最大电缆长度、调制技术、无线电规范、线路编码和位同步（下文还有更多）。</li>
<li><strong>电缆类型。</strong> 选择有屏蔽或非屏蔽双绞线、非双绞线、同轴电缆等。<a href="https://www.computernetworkingnotes.com/networking-tutorials/network-cable-types-and-specifications.html">从这里了解更多电缆类型</a>。</li>
<li><strong>信号类型。</strong> 基带一次一个比特流，就像铁路一样——只支持单向。宽带同时包含多个比特流，就像双向高速公路一样。</li>
<li><strong>信号传输方法（可能是有线的或无线的）。</strong> 选择包括电（以太网）、光（光纤网络、光纤）、无线电波（802.11 WiFi，a/b/g/n/ac/ax 变种或蓝牙）。如果是无线的话，则要考虑频率：2.5 GHz 还是 5 GHz。如果是有线或以太网的话，则还要考虑网络标准，例如 100BASE-T 和相关标准。</li>
</ul>
<p>第一层的数据单元是比特（bit）。</p>
<p>比特是可传输数字信息的最小单元。比特是二进制的，要么为 0 要么为 1。字节（byte）由八个比特组成，用于表示单个字符，比如字母、数字或符号。</p>
<p>根据硬件设备支持的数据速率（传输速率，每秒或每毫秒的比特数量），比特被发送到硬件设备或从设备发出。这个过程是同步的，从而保持单位时间内发送和接收比特的数量相等（这被称为比特同步）。比特的传输方式由信号的传输方式决定。</p>
<p>节点可以发送比特、接收比特，或者收发兼顾。如果节点只能收或只能发，那么该节点采用的就是单工模式。如果节点既可以收又可以发，那么该节点采用的就是双工模式。如果一个节点可以同时进行收发操作，那么它就是全双工的，否则就是半双工的。</p>
<p>最初的以太网是半双工的。如果采用了正确的设备，现在也可以选择全双工的以太网。</p>
<h3 id="">如何排查第一层中的问题</h3>
<p>这里是第一层中要当心的一些问题：</p>
<ul>
<li>电缆失效，例如电线损坏或连接器损坏</li>
<li>网络硬件设备故障，例如电路损坏</li>
<li>东西正被拔出（我们都遇到过……）</li>
</ul>
<p>如果第一层出了问题，第一层以上的任何东西都不会正常工作。</p>
<h3 id="tldr">TL;DR</h3>
<p><em>第一层包含的是基础设施，它让网络通信变成可能。</em></p>
<p><em>它定义了用于激活、维护和停用网络设备之间的物理连接的电气、机械、程序和功能规范。</em>——<a href="https://learning.oreilly.com/videos/wireshark-for-packet/9781839212352/9781839212352-video3_11">来源</a></p>
<p>有趣的事实：深海通信电缆在全世界传输数据。这张地图会让你大开眼界：<a href="https://www.submarinecablemap.com/">https://www.submarinecablemap.com/</a>。</p>
<p>因为你已经坚持到这儿了，所以送你一只考拉：</p>
<figure>
    <img src="https://chinese.freecodecamp.org/news/content/images/2021/11/4-Koala.jpeg" alt="考拉、自然、动物、爪子、澳大利亚、幼仔" width="600" height="400" loading="lazy">
    <figcaption><a href="https://pixabay.com/photos/koala-nature-animals-paws-630117/">来源</a></figcaption>
</figure>
<h2 id="osi">OSI 第二层</h2>
<p>第二层是 <strong>数据链路层</strong>。它定义了数据的传输格式、可以在节点间流动的数据量大小、数据流动可以持续的时长，以及在流中检测到错误时应采取的措施。</p>
<p>使用更加正式的技术术语描述如下：</p>
<ul>
<li><strong>线路规划。</strong> 谁应该交流多久？节点传输信息的时间应该持续多久？</li>
<li><strong>流量控制。</strong> 应该传输的数据量是多少？</li>
<li><strong>错误控制-检测和校正。</strong> 从电尖峰脉冲到卑鄙的连接器，所有的数据传输方法都有可能出错。一旦第二层的技术告知网络管理员有关第二层或第一层的问题，系统管理员就能为后续几层纠正那些错误。第二层主要关心的是错误检测，而不是错误校正。（<a href="https://learning.oreilly.com/videos/wireshark-for-packet/9781839212352/9781839212352-video3_10">来源</a>）</li>
</ul>
<p>第二层内有两个截然不同的子层：</p>
<ul>
<li><strong>介质访问控制（MAC，Media Access Control）：</strong> MAC 子层负责分配硬件标识号，这个标识号被称为 MAC 地址，它能够唯一标识网络上的各个设备。两个设备不应该有相同的 MAC 地址。MAC 地址在硬件制造时就分配好了，位于网卡当中，大多数网络都会自动对其进行识别。交换机会跟踪网络上所有的 MAC 地址。在<a href="https://www.pcmag.com/encyclopedia/term/mac-address">这里</a>和<a href="https://people.richland.edu/dkirby/141macaddress.htm">这里</a>了解更多有关 MAC 地址的信息，在<a href="https://www.networkworld.com/article/3584876/what-is-a-network-switch-and-how-does-it-work.html">这里</a>进一步了解网络交换机。</li>
<li><strong>逻辑链路控制（LLC，Logical Link Control）:</strong> LLC 子层处理帧的寻址以及流量控制。速度取决于两个节点之间的链路，例如以太网或 Wifi。</li>
</ul>
<p>第二层的数据单元是 <em>帧（frame）。</em></p>
<p>每一帧都包括一个帧头、主体和一个帧尾：</p>
<ul>
<li>帧头：通常包括源节点和目的节点的 MAC 地址。</li>
<li>主体：由要传输的比特组成。</li>
<li>帧尾：包括错误检测信息。当检测到错误时，根据实现或网络的配置或协议，帧可能被丢弃，或者错误会被报告给上面的层，用于进一步错误校正。例如，错误检测机制的有循环冗余校验（CRC，Cyclic Redundancy Check）和帧校验序列（FCS，Frame Check Sequence）。<a href="http://www.msc.uky.edu/ken/cs471/notes/chap5.htm">从这里了解更多有关错误检测技术的信息</a>。</li>
</ul>
<figure>
    <img src="https://chinese.freecodecamp.org/news/content/images/2021/11/5-Frame-Example.jpeg" width="600" height="400" alt="5-Frame-Example" loading="lazy">
    <figcaption><a href="https://learning.oreilly.com/library/view/the-illustrated-network/9780128110287/xhtml/chp001.xhtml">来源</a></figcaption>
</figure>
<p>帧的大小通常有一个最大值，这个值被称为最大传输单元（MTU，Maximum Transmission Unit）。巨型帧的大小超过了标准的 MTU，<a href="https://kb.netgear.com/25091/Guidance-on-the-use-of-jumbo-frames">从这里了解更多有关巨型帧的信息</a>。</p>
<h3 id="osi">如何排查 OSI 第二层中的问题</h3>
<p>这里是第二层中要当心的一些问题：</p>
<ul>
<li>可能在第一层上发生的所有问题</li>
<li>两个节点间的连接（会话）不成功</li>
<li>成功建立但又间歇性失败的会话</li>
<li>帧冲突</li>
</ul>
<h3 id="tldr">TL;DR</h3>
<p><em>数据链路层允许局域网内的各节点彼此相互通信。这一层建立了线路规划、流量控制和错误控制的基础。</em></p>
<h2 id="osi">OSI 第三层</h2>
<p>第三层是 <strong>网络层。</strong> 就是在这里，我们通过路由器在网络间或跨网发送信息。不仅仅是节点到节点的通信，我们现在还可以进行网络到网络的通信了。</p>
<p>路由器是第三层的主力——它们是在第三层中必不可少。路由器跨越多个网络移动数据包。</p>
<p>路由器不仅通过连接到网络服务提供商（ISPs，Internet Service Providers）提供因特网访问，还跟踪着所在网络中的一切（记住交换机跟踪的是一个网络中所有的 MAC 地址），它所连接的其它网络，以及在这些网络中路由数据包的不同路径。</p>
<p>路由器将所有的地址和路由信息都保存在路由表中。</p>
<p>这里是一个简单的路由表示例：</p>
<figure>
    <img src="https://chinese.freecodecamp.org/news/content/images/2021/11/6-Routing-Table.png" width="600" height="400" alt="6-Routing-Table" loading="lazy">
    <figcaption><a href="https://www.geeksforgeeks.org/routing-tables-in-computer-network/">图片来源 + 从这里了解更多有关路由表的信息</a></figcaption>
</figure>
<p>第三层的数据单元是 <em>数据包（data packet）</em>。通常，每个数据包都包含一个帧 <strong>加上</strong> 一个 IP 地址信息的包装。换句话说，帧被第三层的地址信息封装了。</p>
<p>数据包中传输的数据有时也被称为 <em>负载（payload）</em>。每个包都拥有到达目的地所需的一切，但是它能不能成功抵达就是另外一回事儿了。</p>
<p>第三层上的传输是无连接的、尽力而为的——除了将流量发往它应该去的地方，它们不会做任何事。更多与数据传输有关的协议在第四层。</p>
<p>节点一旦连接到因特网，它就会被赋予一个因特网协议（IP，Internet Protocol）地址，它看起来要么像 172.16.254.4（IPv4 地址），要么像 2001:0db8:85a3:0000:0000:8a2e:0370:7334（IPv6 地址）。路由器在它们的路由表中使用 IP 地址。</p>
<p>IP 地址通过地址解析协议（ARP，Address Resolution Protocol）与物理节点的 MAC 地址相关联，ARP 用节点对应的 IP 地址解析 MAC 地址。</p>
<p>ARP 通常被认为是第二层的一部分，但是由于 IP 地址在第三层以下都不存在，所以 ARP 也是第三层的一部分。</p>
<h3 id="">如何排查第三层中的问题</h3>
<p>这里是第三层中要当心的一些问题：</p>
<ul>
<li>所有可能在之前各层中出现的问题 :)</li>
<li>路由器或其它节点故障或无功能</li>
<li>IP 地址配置不正确</li>
</ul>
<p>很多第三层问题的答案都要求使用像 <em>ping</em>、<em>trace</em>、<em>show ip route</em> 或 <em>show ip protocols</em> 这样的命令行工具。在<a href="https://www.pearsonitcertification.com/articles/article.aspx?p=1730891">这里</a>了解更多与有关一至三层问题排查的信息。</p>
<h3 id="tldr">TL;DR</h3>
<p><em>第三层允许节点连接到因特网并跨越不同网络发送数据。</em></p>
<h2 id="osi">OSI 第四层</h2>
<p>第四层是 <strong>传输层</strong>。在这里，我们会深入探讨了两个节点之间连接的具体细节，以及信息是如何在它们之间进行传输的。第四层建立在第二层的功能之上——线路规划、流量控制和错误控制。</p>
<p>这一层也负责数据包的分段，或者说数据包如何被拆分成小片并发往整个网络。</p>
<p>不像上一层，第四层也理解整个消息，而不只是每个独立的数据包的内容。根据对整个消息的理解，第四层不再一次性发送所有数据包，从而管理网络拥塞。</p>
<p>第四层的数据单元有好几个不同的名字，对于 TCP 而言，数据单元是数据包。对于 UDP 而言，包被称为数据报（datagram）。为了简化，我将只使用数据包这个术语。</p>
<p>第四层中最有名的两个协议是传输控制协议（TCP，Transmission Control Protocol）和用户数据报协议（UDP，User Datagram Protocol）。</p>
<p>TCP 是一个面向连接的协议，优先保证的是数据的质量而不是速度。</p>
<p>TCP 显式地与目的节点建立连接，并要求在数据传输时进行源节点与目的节点之间的握手操作。握手能够确认数据已经被接收。如果目的节点没有收到所有的数据，TCP 就会要求进行重传。</p>
<p>TCP 也会确保数据包以正确的顺序交付或者重组。<a href="https://www.cloudflare.com/learning/ddos/glossary/tcp-ip/">从这里了解更多有关 TCP 的信息</a>。</p>
<p>UDP 是一个无连接的协议，优先保证速度而不是数据的质量。UDP 不要求进行握手，这也正是它被称为无连接的原因。</p>
<p>因为 UDP 不必等待确认，所以它可以以更快的速度发送数据，但并非所有的数据都能成功传输，我们也不会知道哪些数据传输失败了。</p>
<p>如果信息被拆分成多个数据报，除非这些数据报都包含一个序列号，否则 UDP 无法确保以正确的顺序重组数据包。<a href="https://www.cloudflare.com/learning/ddos/glossary/user-datagram-protocol-udp/">从这里了解更多有关 UDP 的信息</a>。</p>
<p>TCP 和 UDP 都将数据发往网络设备上的特定端口，这些网络设备都有自己的 IP 地址。IP 地址和端口号的组合被称为套接字（socket）。</p>
<p><a href="https://www.dummies.com/programming/networking/cisco/network-basics-tcpudp-socket-and-port-overview/">从这里了解更多有关套接字的信息</a>。</p>
<p>从<a href="https://www.geeksforgeeks.org/differences-between-tcp-and-udp/">这里</a>和<a href="https://www.pearsonitcertification.com/articles/article.aspx?p=2873377">这里</a>了解 TCP 与 UDP 这两个协议之间的更多差异和相似之处。</p>
<h3 id="osi">如何排查 OSI 第四层中的问题</h3>
<p>这里是第四层中要当心的一些问题：</p>
<ul>
<li>所有可能在之前各层中出现的问题 :)</li>
<li>被封锁的端口——检查你的访问控制列表（ACL，Access Control List）和防火墙</li>
<li>服务质量（QoS，Quality of Service）设置。QoS 是路由器/交换机的一个功能，可以对流量进行优先级排序，并且它们真的可以把事情搞砸。<a href="https://www.pcworld.com/article/2689995/quality-of-service-explained-how-routers-with-strong-qos-make-better-home-networks.html">从这里学习更多有关 Qos 的信息</a>。</li>
</ul>
<h3 id="tldr">TL;DR</h3>
<p><em>传输层通过将消息分割成多个数据包提供端到端的消息传输，支持面向连接的和无连接的通信。</em></p>
<h2 id="osi">OSI 第五层</h2>
<p>第五层是 <strong>会话层</strong>，负责建立、维持和终止会话。</p>
<p>会话建立在两个网络应用之间，是双方商定好的连接。注意，我们没有说两个节点，我们已经离开节点了，它们是第四层中的东西。</p>
<p>开玩笑的，我们还是有节点的，但是第五层不需要保留节点的概念，因为它是之前各层抽象出来的（关心）的概念。</p>
<p>所以会话是一个建立在两个特定的用户应用之间的连接，其中有一些重要的概念需要考虑：</p>
<ul>
<li>客户端与服务器模型：请求信息的应用被称为客户端，拥有被请求信息的应用被称为服务器。</li>
<li>请求与响应模型：在建立会话的过程和会话期间，不断有来回的信息请求，还有包含被请求信息的响应或者是“嘿，我没有你要的东西”。</li>
</ul>
<p>会话持续的时间可以非常短，也可以非常长，有时会话也可能会失败。</p>
<p>根据所采用的协议，会话可能会启动各种故障解决程序。根据所使用的应用程序/协议/硬件，会话可能支持单工，半双工或全双工模式。</p>
<p>第五层中协议的例子有网络基本输入输出系统（NetBIOS，Network Basic Input Output System）和远程过程调用协议（RPC，Remote Procedure Call Protocol）等等。</p>
<p>从这里往上（第五层及以上），网络关注的是与用户应用程序建立连接以及如何向用户展示数据。</p>
<h3 id="osi">如何诊断 OSI 第五层中的问题</h3>
<p>这里是第五层中需要当心的一些问题：</p>
<ul>
<li>服务器不可用</li>
<li>服务器未被正确地配置，例如 Apache 或 PHP 配置</li>
<li>会话故障——断连、超时，等等</li>
</ul>
<h3 id="tldr">TL;DR</h3>
<p><em>会话层负责初始化、维持并终止两个用户应用程序之间的连接。它响应来自表示层的请求，并向传输层发起请求。</em></p>
<h2 id="osi">OSI 第六层</h2>
<p>第六层是 <strong>表示层</strong>，负责数据的格式，比如字符编码与转换，以及数据加密。</p>
<p>托管用户应用程序的操作系统通常包含第六层中的程序，这个功能并不总是被网络协议实现。</p>
<p>第六层确保第七层中的用户程序可以成功地消费数据，当然还有最终数据的展示。</p>
<p>有三种数据格式化方法需要注意：</p>
<ul>
<li>美国信息交换标准代码（ASCII，American Standard Code for Information Interchange）：这个七位编码技术是字符编码中使用最广泛的标准。ASCII 的一个超集是 ISO-885901，它提供了西欧语言所必需的大多数字符。</li>
<li>扩充的二进制编码的十进制交换码（EBDCIC，Extended Binary-Coded Decimal Interchange Code）：由 IBM 设计，用于大型机。此编码与其他字符编码方法不兼容。</li>
<li>万国码（Unicode）：可以使用 32 位，16 位或 8 位字符的字符编码，它尝试容纳所有已知的字母。</li>
</ul>
<p>从<a href="https://www.ibm.com/support/knowledgecenter/ssw_ibm_i_73/nls/rbagsunicodeandprior.htm">这里</a>、<a href="https://www.smashingmagazine.com/2012/06/all-about-unicode-utf8-character-sets/">这里</a>还有<a href="https://kunststube.net/encoding/">这里</a>了解有关字符编码的更多信息。</p>
<p>加密：SSL 或 TLS 加密协议位于第六层。这些加密协议为网络上的节点提供身份认证和数据加密功能，帮助确保传输的数据抵御恶意用户的攻击。TLS 是 SSL 继任者。</p>
<h3 id="osi">如何诊断 OSI 第六层中的问题</h3>
<p>这里是第六层中需要当心的一些问题：</p>
<ul>
<li>驱动程序不存在或损坏</li>
<li>操作系统用户访问级别不正确</li>
</ul>
<h3 id="tldr">TL;DR</h3>
<p><em>表示层负责格式化与加密数据。</em></p>
<h2 id="osi">OSI 第七层</h2>
<p>第七层是 <strong>应用层</strong>。</p>
<p>顾名思义，这一层最终负责支持用户程序使用的服务。应用程序包括安装在操作系统中的软件程序，比如因特网浏览器（例如 Firefox）或文字处理程序（例如 Microsoft Word）。</p>
<p>应用程序可以在后台执行专门的网络功能，也可以要求第七层中专门的服务。</p>
<p>例如专门创建电子邮件程序，它在网络上运行并利用第七层中网络功能（比如电子邮件协议）。</p>
<p>应用程序也可以控制用户交互，比如安全检查（例如 MFA）、识别两名参与者的身份、初始化信息交换等。</p>
<p>这一层中运行的协议包括文件传输协议（FTP，File Transfer Protocol）、安全壳协议（SSH，Secure Shell）、简单邮件传输协议（SMTP，Simple Mail Transfer Protocol）、因特网消息访问协议（IMAP，Internet Message Access Protocol）、域名服务（DNS，Domain Name Service）和超文本传输协议（HTTP，Hypertext Transfer Protocol）。</p>
<p>虽然这些协议中的每一个都服务于不同的功能，运行的方式也各不相同，但从较高的层次看，它们都促进了信息的交流。</p>
<h3 id="osi">如何诊断 OSI 第七层中的协议</h3>
<p>这里是第七层中需要当心的一些问题：</p>
<ul>
<li>所有之前各层中的问题</li>
<li>软件应用程序配置不正确</li>
<li>用户操作失误（我们都遇到过……）</li>
</ul>
<h3 id="tldr">TL;DR</h3>
<p><em>应用层拥有用户应用程序运行所需的服务和功能，不包括应用程序本身。</em></p>
<h1 id="">结论</h1>
<p>我们第一层中出现的小考拉已经长大了。</p>
<p><img src="https://chinese.freecodecamp.org/news/content/images/2021/11/6-Koala-Makeup.jpeg" alt="6-Koala-Makeup" width="600" height="400" loading="lazy"></p>
<p>学习检查——你能给考拉化妆吗？</p>
<p>没有考拉？</p>
<p>好吧——那就回答这些问题。我保证，这是第二好的选择：</p>
<ul>
<li>什么是 OSI 模型？</li>
<li>每一层分别是什么？</li>
<li>如何使用这些信息去排查网络问题？</li>
</ul>
<p>恭喜！你离理解我们称之为“因特网”的这个宏大实体又进了一步。</p>
<h2 id="">学习资源</h2>
<p>很多非常聪明的人已经写了有关 OSI 模型或特定层的整本书。我鼓励读者阅读 O'Reilly 出版的有关该主题的书，或者网络工程方面的书籍。</p>
<p>这里是我撰写本文时用到的一些资源：</p>
<ul>
<li>The Illustrated Network, 2nd Edition</li>
<li>Protocol Data Unit (PDU):  <a href="https://www.geeksforgeeks.org/difference-between-segments-packets-and-frames/">https://www.geeksforgeeks.org/difference-between-segments-packets-and-frames/</a></li>
<li>Troubleshooting Along the OSI Model:  <a href="https://www.pearsonitcertification.com/articles/article.aspx?p=1730891">https://www.pearsonitcertification.com/articles/article.aspx?p=1730891</a></li>
<li>The OSI Model Demystified:  <a href="https://www.youtube.com/watch?v=HEEnLZV2wGI">https://www.youtube.com/watch?v=HEEnLZV2wGI</a></li>
<li>OSI Model for Dummies:  <a href="https://www.dummies.com/programming/networking/layers-in-the-osi-model-of-a-computer-network/">https://www.dummies.com/programming/networking/layers-in-the-osi-model-of-a-computer-network/</a></li>
</ul>
<h3 id="">关于我</h3>
<p>Chloe Tucker 是位于俄勒冈州波特兰的一名艺术家和计算机科学爱好者。她以前是一名教育工作者，一直在寻找学与教，技术与艺术的交集。你可以通过 Twitter <a href="https://twitter.com/_chloetucker">@_chloetucker</a> 与她联系，还可以访问她的网站 <a href="https://chloe.dev/">chloe.dev</a>。</p>
<!--kg-card-end: markdown--><p>原文：<a href="https://www.freecodecamp.org/news/osi-model-networking-layers-explained-in-plain-english/">The OSI Model – The 7 Layers of Networking Explained in Plain English</a>，作者：<a href="https://www.freecodecamp.org/news/author/chloe/">Chloe Tucker</a></p> ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
