<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>通信协议 &#8211; 寂静花园</title>
	<atom:link href="https://www.addesp.com/archives/tag/%E9%80%9A%E4%BF%A1%E5%8D%8F%E8%AE%AE/feed" rel="self" type="application/rss+xml" />
	<link>https://www.addesp.com</link>
	<description>寂静中交织着热情</description>
	<lastBuildDate>Sat, 09 Nov 2024 13:30:51 +0000</lastBuildDate>
	<language>zh-Hans</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=7.1.2</generator>
	<item>
		<title>BitTorrent 扩展协议（Extension Protocol）详解</title>
		<link>https://www.addesp.com/archives/5563</link>
					<comments>https://www.addesp.com/archives/5563#respond</comments>
		
		<dc:creator><![CDATA[ADD-SP]]></dc:creator>
		<pubDate>Tue, 18 Jan 2022 09:43:19 +0000</pubDate>
				<category><![CDATA[BitTorrent 协议簇详解]]></category>
		<category><![CDATA[通信协议]]></category>
		<guid isPermaLink="false">https://www.addesp.com/?p=5563</guid>

					<description><![CDATA[BitTorrent 扩展协议（Extension Protocol）为  BitTorrent  协议簇提供了一个简单而轻量的扩展方式，可以在保证兼容性的同时为协议加入新的功能。比如基于 DHT 协议的磁力链接就是使用扩展协议加入的新功能。
本文将介绍 BT 扩展协议的报文格式和时序。]]></description>
										<content:encoded><![CDATA[
<h2 class="wp-block-heading">概述</h2>



<p class="wp-block-paragraph">一个协议从制定之初就不可能是完美的，总是要根据具体情况扩展功能，但扩展功能的同时要考虑与旧版本协议的兼容性，否则当一个用户升级了新的协议后，可能之前的许多功能就不能用，因为可能大多数人还没有升级。</p>



<p class="wp-block-paragraph">BitTorrent 扩展协议（Extension Protocol）为  BitTorrent  协议簇提供了一个简单而轻量的扩展方式，可以在保证兼容性的同时为协议加入新的功能。比如基于 <a href="/archives/5428" target="_blank" rel="noreferrer noopener" title="DHT 协议">DHT 协议</a> 的磁力链接就是使用扩展协议加入的新功能。</p>



<p class="wp-block-paragraph">本文将介绍 BT 扩展协议的报文格式和时序。</p>



<h2 class="wp-block-heading">回顾“<a href="/archives/5271" target="_blank" rel="noreferrer noopener" title="伙伴（Peer）协议">伙伴（Peer）协议</a>”</h2>



<p class="wp-block-paragraph">伙伴（Peer）协议在完成握手后，为每一种消息都指定了一个唯一的 ID，并且每次发送消息时，都要在消息的最开始处填充本次消息的字节长度，这个长度也包含“长度”这项数据本身占据的空间。</p>



<p class="wp-block-paragraph">伙伴（Peer）协议中并没有可以用于扩展功能的消息类型，所以扩展协议为此新增了一个消息类型，并指定了唯一的 ID，即 <code>extended</code> 消息，ID 是 <code>20</code>。</p>



<h2 class="wp-block-heading">“扩展”消息</h2>



<p class="wp-block-paragraph">扩展消息的用处是完成扩展协议本身的握手流程，并且协助其它协议的工作，比如协助  <a href="/archives/5428" target="_blank" rel="noreferrer noopener" title="DHT 协议">DHT 协议</a> 传输 DHT 节点的 UDP 端口。</p>



<p class="wp-block-paragraph">扩展消息的 ID 为 20，当程序发送这一消息时，其布局是下面这样的，</p>



<figure class="wp-block-table is-style-stripes"><table class="has-fixed-layout"><tbody><tr><td class="has-text-align-center" data-align="center">第 0 ~ 3 个字节</td><td class="has-text-align-center" data-align="center">第 4 个字节</td><td class="has-text-align-center" data-align="center">第 5 个字节</td><td class="has-text-align-center" data-align="center">若干个字节</td></tr><tr><td class="has-text-align-center" data-align="center">整个消息的长度</td><td class="has-text-align-center" data-align="center">消息的 ID（20）</td><td class="has-text-align-center" data-align="center">扩展消息的 ID</td><td class="has-text-align-center" data-align="center">载荷（payload）</td></tr></tbody></table><figcaption>extended 消息布局</figcaption></figure>



<p class="wp-block-paragraph">报文中的第五个字节如果为 0 则表示这是握手消息，如果大于 0 则表示为其它协议的消息。报文中的载荷当扩展消息 ID 为 0 是是握手消息的载荷，其它情况下则由具体的协议规定，比如  <a href="/archives/5428" target="_blank" rel="noreferrer noopener" title="DHT 协议">DHT 协议</a> 就规定了载荷的格式。</p>



<h2 class="wp-block-heading">握手消息</h2>



<p class="wp-block-paragraph">握手消息应当在 <a href="/archives/5271" target="_blank" rel="noreferrer noopener" title="伙伴（Peer）协议">伙伴（Peer）协议</a> 完成握手后立即发送给对方，一方收到握手消息后，也可以向对方发送握手消息用来禁用某个协议，或者协商某个协议。</p>



<p class="wp-block-paragraph">握手消息的载荷是一个经过了 B 编码的字典。下面列出的所有的字典中的项目都是可选的，任何一个未知的项目都应该被忽略，字典的全部内容都是区分大小写的。</p>



<p class="wp-block-paragraph">这个字典中包含下列内容。</p>



<ul class="wp-block-list"><li>m：一个字典，从一个字符串映射到一个非负整数。字符串是受支持的协议的名称，非负整数是这个协议的 ID。协议的名称必须是唯一的，ID 则只需要保证对于通信双方唯一即可。如果 ID 为 0 则表示发送方希望禁用这个 ID 对应的协议。</li><li>p：一个整数，表示发送握手消息的一方监听的 TCP 端口号。对于握手消息的接收方，通常不需要发送这一项，因为对方只有在知道了监听端口后才能够向其发送握手消息。</li><li>v：客户端的名称（UTF-8），比如 “uTorrent 1.2”。</li><li>yourip：一个字符串，表示握手消息发送方看到的接收方的 IP 地址的紧凑表。消息的接收方可能持有多个 IP 地址，这一项可以告诉接收方它的哪个 IP 被发送方所使用。</li><li>ipv6：如果发送方持有一个或多个 IPV6 地址，则应该将这些 IPV6 地址以紧凑表的形式写入到这一项中。</li><li>ipv4：基本同 <code>ipv6</code>。</li><li>reqq：一个整数，表示发送方允许多少个消息排队处理，超出此数量后消息可能会被丢弃。</li></ul>



<p class="wp-block-paragraph">这种握手消息比较奇怪，通常来说，一方发送握手消息后，另一方会以另外的格式来回复握手消息，比如 TLS 的 ClientHello 消息和 ServerHello 消息。但这里握手消息无论是发送还是回复都遵循同一种格式，不过也意料之中，毕竟 P2P 网络中不区分客户端和服务端。</p>



<p class="wp-block-paragraph">举个例子来直观地了解一下握手消息。</p>



<p class="wp-block-paragraph"><code>d1:md11:LT_metadatai1e6:ut_pexi2ee1:pi6881e1:v12:uTorrent 1.2e</code></p>



<p class="wp-block-paragraph">上面就是一个合法的握手消息的载荷，如果将其转化为 JSON 格式则是下面这样。</p>



<pre class="wp-block-code language-json"><code>{
    "m": {
        "LT_metadata": 1,
        "ut_pex": 2
    },
    "p": 6881,
    "v": "uTorrent 1.2"
}</code></pre>



<h2 class="wp-block-heading">参考资料</h2>



<p class="wp-block-paragraph"><a href="https://www.bittorrent.org/beps/bep_0010.html" target="_blank" rel="noreferrer noopener" title="Extension Protocol">Extension Protocol</a></p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.addesp.com/archives/5563/feed</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>BitTorrent 分布式散列表（DHT）协议详解</title>
		<link>https://www.addesp.com/archives/5428</link>
					<comments>https://www.addesp.com/archives/5428#respond</comments>
		
		<dc:creator><![CDATA[ADD-SP]]></dc:creator>
		<pubDate>Sat, 16 Oct 2021 15:26:02 +0000</pubDate>
				<category><![CDATA[BitTorrent 协议簇详解]]></category>
		<category><![CDATA[分布式散列表]]></category>
		<category><![CDATA[通信协议]]></category>
		<guid isPermaLink="false">https://www.addesp.com/?p=5428</guid>

					<description><![CDATA[DHT 协议大幅度提高了 BitTorrent 网络的容错性，使整个网络难以因 Tracker 服务器的下线而崩溃，而这一切的外在表现就是“磁力链接”。]]></description>
										<content:encoded><![CDATA[
<h2 class="wp-block-heading">概述</h2>



<p class="wp-block-paragraph">DHT 协议大幅度提高了 BitTorrent 网络的容错性，使整个网络难以因 Tracker 服务器的下线而崩溃，而这一切的外在表现就是“磁力链接”。</p>



<p class="wp-block-paragraph">DHT 协议涉及到分布式散列表的相关知识，请参考<a href="/archives/5338" target="_blank" rel="noreferrer noopener" title="/archives/5338">分布式散列表协议 —— Kademlia 详解</a>。</p>



<p class="wp-block-paragraph">下文将 ”BitTorrent 软件“ 简称为 &#8220;BT 软件“。</p>



<h2 class="wp-block-heading">为什么需要 DHT 协议？</h2>



<p class="wp-block-paragraph"><a href="/archives/5271" target="_blank" rel="noreferrer noopener" title="/archives/5271">伙伴（Peer）协议</a>可以让 BitTorrent 节点之间互相交换已知信息来完整下载和上传。当然这一切的前提是我们能够知道其它节点的联系方式，没有了这个前提，我们只能以 0KB/s 的速度等待了。<a href="/archives/5271" target="_blank" rel="noreferrer noopener" title="/archives/5271">Tracker 协议</a>用于查询可以帮助下载和上传的节点，有了节点的联系方式我们才能通过伙伴（Peer）协议来交换数据完成下载和上传。但是 Tracker 是一个中心的服务器，一旦 Tracker 服务器下线，那么网络中的所有节点就只能抓瞎了。</p>



<p class="wp-block-paragraph">可见 Tracker 服务器是整个 BitTorrent 网络的弱点，究其本质其实是因为节点的联系方式都存储在一个固定的位置，容错性很差。如果将这些信息存储在整个 BitTorrent 网络中，那么少数节点的故障并不会导致联系方式的丢失，也就不会影响整个网络的运行。这就是 DHT 协议的任务 —— 将每个节点变成一个小型 Tracker。</p>



<h2 class="wp-block-heading">磁力链接</h2>



<p class="wp-block-paragraph">当你使用 BT 软件下载的时候你可能见过下面这样的地址。</p>



<pre class="wp-block-code language-URL"><code>magnet:?xt=urn:btih:c9e15763f722f23e98a29decdfae341b98d53056&amp;dn=Cosmos+Laundromat&amp;tr=udp%3A%2F%2Fexplodie.org%3A6969&amp;tr=udp%3A%2F%2Ftracker.coppersurfer.tk%3A6969&amp;tr=udp%3A%2F%2Ftracker.empire-js.us%3A1337&amp;tr=udp%3A%2F%Ftracker.leechers-paradise.org%3A6969&amp;tr=udp%3A%2F%2Ftracker.opentrackr.org%3A1337&amp;tr=wss%3A%2F%2Ftracker.btorrent.xyz&amp;tr=wss%3A%2F%2Ftracker.fastcast.nz&amp;tr=wss%3A%2F%2Ftracker.openwebtorrent.com&amp;ws=https%3A%2F%2Fwebtorrent.io%2Ftorrents%2F&amp;xs=https%3A%2F%2Fwebtorrent.io%2Ftorrents%2Fcosmos-laundromat.torrent</code></pre>



<p class="wp-block-paragraph">看起来很长，其实这个链接可以简化。</p>



<pre class="wp-block-code language-url"><code>magnet:?xt=urn:btih:c9e15763f722f23e98a29decdfae341b98d53056</code></pre>



<p class="wp-block-paragraph">严格来说上面的已经是最简版本了，但是对于现在的 BT 软件，如果你输入一个含有 40 个十六进制字符的字符串，它会自动帮你转为磁力链接。</p>



<pre class="wp-block-code language-url"><code>c9e15763f722f23e98a29decdfae341b98d53056</code></pre>



<p class="wp-block-paragraph">所以说最重要的就是这个十六进制字符串。你可以把用你的 BT 软件下载这段字符串，下载下来的视频还挺有趣的。</p>



<p class="wp-block-paragraph">上面这段十六进制字符串是通过哈希算法生成，每份资源丢到哈希算法里都会得到这样的一个字符串，并且仅属于这份资源（大概），也就是我们在之前的系列文章中提到的 <code>info_hash</code>。</p>



<h2 class="wp-block-heading">工作流程</h2>



<p class="wp-block-paragraph">当节点上线时它会随机生成一个节点 ID 并作为自己的 ID 使用。</p>



<p class="wp-block-paragraph">初始状态下我们并不知道其它节点的联系方式，此时需要通过其它方式或者，比如 Trakcer 服务器，或者 <code>.torrent</code> 文件中写明的联系方式。</p>



<p class="wp-block-paragraph">然后我们会与节点建立联系并构建路由表，并周期性地测试节点的联通状态，比如通信时延。通过此种方式我们获得了一个通信质量良好的节点列表。这时伙伴交换（Peer Exchange）协议也开始工作，我们会和越来越多的节点建立联系。</p>



<p class="wp-block-paragraph">当我们想下载一个文件时，我们计算文件 ID 和已知节点之间的距离，从自己的路由表中选择距离最近的若干个节点发起查询请求，接收到请求的节点如果正好可以提供这个文件则可以直接开始下载，反之它们会从自己的路由表中选择距离最近的若干个节点返回。</p>



<p class="wp-block-paragraph">当我们向上传某些文件时（做种），我们会计算文件的 ID，然后将自己的联系方式存储到距离文件 ID 最近的若干个节点中。</p>



<h3 class="wp-block-heading">人话</h3>



<p class="wp-block-paragraph">我们做种时总会把自己的联系方式存储到一个很小的范围内，此范围由文件的 ID 决定。当我们想下载时，会根据文件 ID 计算出这个范围，然后从里找做种的人就行了。</p>



<h2 class="wp-block-heading">协议概述</h2>



<p class="wp-block-paragraph">DHT 协议是一个基于 <a href="/archives/5338" target="_blank" rel="noreferrer noopener" title="/archives/5338">Kademila 协议</a>并使用 UDP 传输的应用协议，它可以将每个节点变成一个小型 Tracker，避免中心化的 Tracker 服务器所带来的风险。</p>



<p class="wp-block-paragraph">DHT 协议的基础部分和  <a href="/archives/5338" target="_blank" rel="noreferrer noopener" title="/archives/5338">Kademila 协议</a>一致，比如节点的 ID 都是 160 位的二进制数，使用异或算法计算距离和使用相同方法构建路由表。不同的地方在于 DHT 协议更改了部分 RPC 过程，并将这些 RPC 集合命名为 KRPC 协议。</p>



<h2 class="wp-block-heading">KRPC 协议</h2>



<p class="wp-block-paragraph">KRPC 协议是一个由 UDP 数据包和其包裹的经过 B 编码字典组成的简洁的 RPC 协议。每次查询只会有一次响应，没有重发/重试这种机制。</p>



<p class="wp-block-paragraph">下面是三种消息类型。</p>



<ul class="wp-block-list"><li>query（查询）</li><li>response（响应）</li><li>error（错误）</li></ul>



<p class="wp-block-paragraph">下面是四类查询。</p>



<ul class="wp-block-list"><li>ping</li><li>find_node</li><li>get_peer</li><li>announce_peer</li></ul>



<p class="wp-block-paragraph">KRPC 消息是一个经过 B 编码的字典（dictionary），每个消息至少有三个 key，分别表示”事务 ID“、”消息类型“ 和 ”客户端名称和版本“。根据消息的不同可以有更多的 key。</p>



<h3 class="wp-block-heading">ping</h3>



<p class="wp-block-paragraph">此消息用于检查目标节点的状态，发起者应发送自己的节点 ID，接收者应回复自己的节点 ID。</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><p>喂？听到了么？</p><p>听到了。</p></blockquote>



<h3 class="wp-block-heading">find_node</h3>



<p class="wp-block-paragraph">此消息用于查询指定节点的联系方式（IP 地址和端口），发起者发送目标节点的 ID，接收者会从自己的路由表中选出距离目标节点最近的 k 个节点 ID 并返回。这是一个递归的过程，详情请阅读<a href="/archives/5338" target="_blank" rel="noreferrer noopener" title="/archives/5338">分布式散列表协议 —— Kademlia 详解</a>。</p>



<h3 class="wp-block-heading">get_peers</h3>



<p class="wp-block-paragraph">此消息用于查询于指定的 <code>info_hash</code> 相关的节点的联系方式，功能类似 Trakcer 服务器。发起者应发送 <code>info_hash</code>，接收者应返回与 <code>info_hash</code> 有关的节点列表，如果接收者不知道哪些节点于 <code>info_hash</code> 有关，则从自己的路由表中选出 k 个距离 <code>info_hash</code> 最近的节点并返回。</p>



<h3 class="wp-block-heading">announce_peer</h3>



<p class="wp-block-paragraph">当一个节点于某个 <code>info_hash</code> 有关时（下载或上传），它应当发起此消息。发起者应发送自己的节点 ID、<code>info_hash</code> 和监听端口。接收者应存储接收到的联系方式，将 <code>info_hash</code> 和联系方式关联起来，用于响应 get_peers 消息。</p>



<h2 class="wp-block-heading">参考资料</h2>



<p class="wp-block-paragraph"><a href="https://www.bittorrent.org/beps/bep_0005.html" target="_blank" rel="noreferrer noopener" title="https://www.bittorrent.org/beps/bep_0005.html">DHT Protocol</a></p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.addesp.com/archives/5428/feed</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>BitTorrent Tracker 协议详解</title>
		<link>https://www.addesp.com/archives/5313</link>
					<comments>https://www.addesp.com/archives/5313#comments</comments>
		
		<dc:creator><![CDATA[ADD-SP]]></dc:creator>
		<pubDate>Sun, 03 Oct 2021 13:09:11 +0000</pubDate>
				<category><![CDATA[BitTorrent 协议簇详解]]></category>
		<category><![CDATA[通信协议]]></category>
		<guid isPermaLink="false">https://www.addesp.com/?p=5313</guid>

					<description><![CDATA[BitTorrent 网络内的主机依靠互相交换自身持有的资源来完成资源共享，而 Tracker 协议会告诉你哪些主机有你需要的资源。]]></description>
										<content:encoded><![CDATA[
<h2 class="wp-block-heading">概述</h2>



<p class="wp-block-paragraph">BitTorrent 网络内的主机依靠互相交换自身持有的资源来完成资源共享，而 Tracker 协议会告诉你哪些主机有你需要的资源。</p>



<p class="wp-block-paragraph">本文将详细介绍 Tracker 协议。</p>



<h2 class="wp-block-heading">基于 HTTP 的 Tracker 协议</h2>



<p class="wp-block-paragraph">Tracker 服务器可以使用 HTTP 协议对外提供服务，BitTorrent 客户端只需要向指定的 URL 发送 HTTP GET 请求即可。</p>



<p class="wp-block-paragraph">一个常见的 Tracker URL 可能是这样的：<code>http://tracker.example.org:80/announce</code>。发送 GET 请求时需要附带下列查询字符串。</p>



<ul class="wp-block-list"><li>info_hash：由 <code>.Torrent</code> 文件中的信息计算出的 SHA-1 摘要，并使用 B 编码进行编码。</li><li>peer_id：BitTorrent 客户端启动时随机生成的长度为 20 个字符串。</li><li>ip：可选参数，表示发起请求的 客户端的 IP。一般情况下会在 Tracker 和客户端在同一主机上时使用。</li><li>port：BitTorrent 客户端监听的端口号，此端口号将用于接收其它 BitTorrent 客户端的传入连接。</li><li>uploaded：已经上传的数据总量（字节）。</li><li>downloaded：已经下载的数据总量（字节）。</li><li>left：还需要下载的数据总量（字节）。此数值不能使用参数 <code>downloaded</code> 计算，因为 <code>downloaded</code> 参数包含了那些下载了但是没有通过校验的数据。</li><li>event：可选参数，可能取值为 <code>start</code>、<code>completed</code> 和 <code>stopped</code>。可以分别在下载开始、下载完成和停止下载时发送。</li></ul>



<hr class="wp-block-separator"/>



<p class="wp-block-paragraph">Tracker 服务器收到 GET 请求时应该响应一个使用 B 编码进行编码的字典，如果请求成功则字典中必须包含下列两个键。</p>



<ul class="wp-block-list"><li>interval：一个数字，表示应该等待多少秒后才能重新请求本 Trakcer。</li><li>peers：一个由字典组成的列表，每个列表包含了提供被请求资源的 Peer 的 ID，IP 和端口。</li></ul>



<p class="wp-block-paragraph">如果请求成功，则返回经过 B 编码编码后字典，如果将其使用 JSON 表示则是下面这样。</p>



<pre class="wp-block-code language-json"><code>{
    "interval": 120,
    "peers": &#91;
        { "peer id": "xxxxxxxxxxxxxxxxxxxx", "ip": "192.168.1.1", "port": 7000 },
        { "peer id": "yyyyyyyyyyyyyyyyyyyy", "ip": "192.168.1.2", "port": 7001 }
    ]
}</code></pre>



<p class="wp-block-paragraph">如果请求失败则同样需要返回一个经过 B 编码编码后的字典，且必须包含一个名为 <code>failure reason</code> 的键，其内容是人类可读的错误提示信息。</p>



<p class="wp-block-paragraph">由于 Tracker 的响应可能会很大，比如返回了大量的 Peer 信息，此时再使用 B 编码进行表示则会占用较大的空间。如果客户端不希望这种情况发生，可以在请求时添加一个名为 <code>compact</code> 的参数，并将其值设置为 <code>1</code>，表示建议 Tracker 返回经过紧凑的信息。如果其值为 <code>0</code>，则表示建议 Tracker 返回未经紧凑的信息。</p>



<p class="wp-block-paragraph">所谓紧凑的信息实际就是将键 <code>Peers</code> 的内容转化为二进制发送。下面是一个例子。</p>



<pre class="wp-block-code language-plaintext"><code>// 紧凑前
d8:intervali:120e5:peersl7:peer id20:xxxxxxxxxxxxxxxxxxxx11:192.168.1.1i:7000ee

// 紧凑后 Peer ID 被丢弃
d8:intervali:120e5:peers6:\x1\x1\xA8\xC0\x58\x1B</code></pre>



<h2 class="wp-block-heading">基于 UDP 的 Tracker 协议</h2>



<p class="wp-block-paragraph">基于 HTTP 的 Tracker 协议需要维护一个 TCP 连接，但是通常 Tracker 的请求和响应都不是很大，维护 TCP 连接的代价相比较有点大，于是便有了基于 UDP 的 Tracker 协议。</p>



<p class="wp-block-paragraph">下面是通信流程，IPV6 版本的类似。</p>



<pre class="wp-block-code language-plaintext"><code>Peer                                                        Tracker

Connect Request
+ 8 byte protocol_id
+ 4 byte action ( = 0 )
+ 4 byte transaction_id     -------------------------&gt;
                                                            Connect Response
                                                            + 4 byte action ( = 0 )
                                                            + 4 byte transaction_id
                                                            + 8 byte connection_id
                            &lt;-------------------------
IPV4 Announce Request
+ 8 byte connection_id
+ 4 byte action ( = 1 )
+ 4 byte transaction_id
+ 20 byte string info_hash
+ 20 byte string peer_id
+ 8 byte downloaded
+ 8 byte left
+ 8 byte uploaded
+ 4 byte event
+ 4 byte IP address
+ 4 byte key
+ 4 byte num_want
+ 2 byte port               -------------------------&gt;
                                                            IPV4 Announce Response
                                                            + 4 byte action ( = 1 )
                                                            + 4 byte transaction_id
                                                            + 4 byte interval
                                                            + 4 byte leechers
                                                            + 4 byte seeders
                                                            + 4 * n byte IP address
                                                            + 2 * n byte TCP port
                            &lt;-------------------------      + more</code></pre>



<p class="wp-block-paragraph">大多数参数都已经在 HTTP 版本中出现，此处只说明一些未出现的参数和有改动的参数。</p>



<ul class="wp-block-list"><li>transaction_id：由客户端随机生成的事务 ID，客户端使用此 ID 进行请求时，Tracker 服务器也必须使用同样的 ID 进行响应。</li><li>connection_id：由 Tracker 生成的连接 ID，客户端应该保存此 ID，并在后续请求中使用。Tracker 服务器也应该检查接收到的 ID 是否是预期的。</li><li>event：在 HTTP 版本的协议中此参数的取值为三个字符串或者空。在 UDP 版本中则不同。<ul><li>0 &#8211; none</li><li>1 &#8211; completed</li><li>2 &#8211; started</li><li>3 &#8211; stopped</li></ul></li><li>num_want：整数，表示希望获得的 peer 数量，默认为 <code>-1</code>。</li><li>leechers：整数，表示“吸血者”的数量。“吸血者”指下载多而上传少的用户。</li><li>seeders：整数，表示”做种者“的数量。</li></ul>



<h2 class="wp-block-heading">参考资料</h2>



<ul class="wp-block-list"><li><a href="https://www.bittorrent.org/beps/bep_0003.html" target="_blank" rel="noreferrer noopener">The BitTorrent Protocol Specification</a></li><li><a href="https://www.bittorrent.org/beps/bep_0015.html" target="_blank" rel="noreferrer noopener">UDP Tracker Protocol for BitTorrent</a></li><li><a href="https://www.bittorrent.org/beps/bep_0023.html">Tracker Returns Compact Peer Lists</a></li></ul>
]]></content:encoded>
					
					<wfw:commentRss>https://www.addesp.com/archives/5313/feed</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
		<item>
		<title>BitTorrent 伙伴（Peer）协议详解</title>
		<link>https://www.addesp.com/archives/5271</link>
					<comments>https://www.addesp.com/archives/5271#comments</comments>
		
		<dc:creator><![CDATA[ADD-SP]]></dc:creator>
		<pubDate>Sat, 02 Oct 2021 15:10:12 +0000</pubDate>
				<category><![CDATA[BitTorrent 协议簇详解]]></category>
		<category><![CDATA[通信协议]]></category>
		<guid isPermaLink="false">https://www.addesp.com/?p=5271</guid>

					<description><![CDATA[本文将介绍 伙伴（Peer）协议的握手和通信流程。]]></description>
										<content:encoded><![CDATA[
<h2 class="wp-block-heading">概述</h2>



<p class="wp-block-paragraph">本文将介绍 伙伴（Peer）协议的握手和通信流程。</p>



<p class="wp-block-paragraph">伙伴（Peer）协议是一个运行在 TCP 或者 μTP 协议之上的应用层协议，被用于两个 BitTorrent 客户端之间的通信，如上传和下载。使用本协议通信时所有的字符串均使用 UTF-8 编码。</p>



<p class="wp-block-paragraph">协议可以分为握手流程和通信流程。</p>



<h2 class="wp-block-heading">握手流程</h2>



<p class="wp-block-paragraph">伙伴（Peer）协议由握手消息和无尽的数据流组成，也就是说协议没有规定断开连接前应该做什么，通信双方随时可以断开连接。</p>



<pre class="wp-block-code language-plaintext"><code>Peer A                                                         Peer B

Handshake
+ String "19:BitTorrAnt protocol"
+ Eight resvered bytes
+ 20 byte bencoded info_hash     
+ 20 byte peer id                  ----------------------&gt;
                                                               Handshake
                                                               + String "19:BitTorrAnt protocol"
                                                               + Eight resvered bytes
                                                               + Same 20 byte bencoded info_hash
                                                               + 20 byte peer id  

                                   &lt;----------------------


Application Data                   &lt;---------------------&gt;     Application Data</code></pre>



<p class="wp-block-paragraph">握手流程比较简单，A 首先依次发送下列信息。</p>



<ol class="wp-block-list">
<li>字符串 <code>19:BitTorrent protocol</code>。</li>



<li>八个保留的字节，目前的实现中全部为零。</li>



<li>一个使用 B 编码进行编码的 SHA-1 摘要，此摘要由 .torrent 文件中部分信息计算得出，在不考虑哈希碰撞的情况下每个摘要对应唯一份资源，也就是我们想要下载的资源。</li>



<li>客户端启动时随机生成的 ID。</li>
</ol>



<p class="wp-block-paragraph">B 收到握手消息后应当依次发送下列信息。</p>



<ol class="wp-block-list">
<li>字符串 <code>19:BitTorrent protocol</code>。</li>



<li>八个保留的字节，目前的实现中全部为零。</li>



<li>一个使用 B 编码进行编码的 SHA-1 摘要，要求于收到的摘要一致。</li>



<li>客户端启动时随机生成的 ID。</li>
</ol>



<p class="wp-block-paragraph">最后双方验证下列信息。</p>



<ol class="wp-block-list">
<li>发送的 SHA-1 摘要和接收到的 SHA-1 摘要是否相同。</li>



<li>对方的 ID 是否是自己所期望的。客户端一般都通过其它手段（如 Tracker 协议）提前获知了拥有某资源的 Peer ID 列表，如果对方的 ID 不在这份列表内则连接会被关闭。</li>
</ol>



<p class="wp-block-paragraph">如果上面两个条件同时满足则握手成功，反之则关闭连接。</p>



<h2 class="wp-block-heading">通信流程</h2>



<p class="wp-block-paragraph">握手完成后，接下来发送的任何数据都要遵循一个固定的格式，即”长度+具体数据“，也就是发送的数据中，开头是整个信息的字节大小，紧跟在后面的是”具体数据：，整个信息的字节大小不仅包含“具体数据”的大小，还包含开头的“长度”所占用的空间。</p>



<p class="wp-block-paragraph">通信流程中双方需要保持连接，因此一方可以发送一个长度为 0 的保活（keepalives）消息来确认连接的有效性，并且此消息应该被忽略。一般来说保活消息每两分钟发一次，如果对方有自己需要的数据，则周期可以更短。</p>



<p class="wp-block-paragraph">任何一个非保活消息都以一个单字节开始，不同的值对应着不同类型的消息，这个单字节被称为消息 ID。通信双方通过这些不同类型的消息来完成资源共享。</p>



<p class="wp-block-paragraph">消息 ID 有下列取值。</p>



<ul class="wp-block-list">
<li>0 &#8211; choke</li>



<li>1 &#8211; unchoke</li>



<li>2 &#8211; interested</li>



<li>3 &#8211; not interested</li>



<li>4 &#8211; have</li>



<li>5 &#8211; bitfield</li>



<li>6 &#8211; request</li>



<li>7 &#8211; piece</li>



<li>8 &#8211; cancel</li>
</ul>



<h3 class="wp-block-heading">Choke 消息</h3>



<p class="wp-block-paragraph">此消息不承载任何数据，也就是说发送方只需要发送一个消息 ID 即可。</p>



<p class="wp-block-paragraph">此消息表示在收到 “Unchoke 消息”之前，对方不会发送任何数据。</p>



<h3 class="wp-block-heading">Unchokie 消息</h3>



<p class="wp-block-paragraph">此消息不承载任何数据，也就是说发送方只需要发送一个消息 ID 即可。 </p>



<p class="wp-block-paragraph">如果收到了此消息，并且收到了“interested 消息”，则双方会开始数据传输。</p>



<h3 class="wp-block-heading">Interested 消息</h3>



<p class="wp-block-paragraph">此消息不承载任何数据，也就是说发送方只需要发送一个消息 ID 即可。</p>



<p class="wp-block-paragraph">此消息表示对方<strong>有兴趣</strong>进行数据传输。</p>



<h3 class="wp-block-heading">Not interested 消息</h3>



<p class="wp-block-paragraph">此消息不承载任何数据，也就是说发送方只需要发送一个消息 ID 即可。 </p>



<p class="wp-block-paragraph">此消息表示对方<strong>没有兴趣</strong>进行数据传输。</p>



<h3 class="wp-block-heading">Bitfield 消息</h3>



<p class="wp-block-paragraph">此消息承载了一个位图，表示消息的发送方已经下载了哪些数据块，因为数据是被分割为一个个的数据块的，所以可以根据位图的索引确定对方持有哪些数据块。</p>



<p class="wp-block-paragraph">此消息只能在握手完成后作为首个消息发送，如果没有持有任何数据块则可以不发送此消息。</p>



<h3 class="wp-block-heading">Have 消息</h3>



<p class="wp-block-paragraph">此消息承载一个数字，这个数字是某个数据块的索引，并且这个数据块是对方刚刚下载完毕并通过校验的数据块。</p>



<h3 class="wp-block-heading">Request 消息</h3>



<p class="wp-block-paragraph">此消息承载了数据块的索引，数据块内部的起始偏移（字节），和长度。这个长度通常是 2 的幂，除非它被文件末尾所截断。</p>



<h3 class="wp-block-heading">Cancel 消息</h3>



<p class="wp-block-paragraph">此消息承载了和”request 消息“相同的数据，用于取消之前请求的数据块。通常会在某个数据块即将或已经下载完成时发送，避免对方发送已经下载好的数据。</p>



<h3 class="wp-block-heading">Piece 消息</h3>



<p class="wp-block-paragraph">此消息承载了数据块索引，数据块内部偏移和具体的数据。</p>



<hr class="wp-block-separator has-css-opacity"/>



<p class="wp-block-paragraph">一般来说，客户端应该按照随机的顺序下载每个数据块，随机的顺序有利于让每个客户端持有不同的数据块，这就便于互相交换数据块，加速下载。</p>



<p class="wp-block-paragraph">当且仅当一方收到了”unchoke 消息“，另一方收到了”interested 消息“时，双方才会启动数据传输。</p>



<h2 class="wp-block-heading">参考资料</h2>



<p class="wp-block-paragraph"><a href="https://www.bittorrent.org/beps/bep_0003.html" target="_blank" rel="noreferrer noopener" title="https://www.bittorrent.org/beps/bep_0003.html">The BitTorrent Protocol Specification</a></p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.addesp.com/archives/5271/feed</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>BitTorrent 协议簇概述</title>
		<link>https://www.addesp.com/archives/5236</link>
					<comments>https://www.addesp.com/archives/5236#comments</comments>
		
		<dc:creator><![CDATA[ADD-SP]]></dc:creator>
		<pubDate>Fri, 01 Oct 2021 13:49:43 +0000</pubDate>
				<category><![CDATA[BitTorrent 协议簇详解]]></category>
		<category><![CDATA[通信协议]]></category>
		<guid isPermaLink="false">https://www.addesp.com/?p=5236</guid>

					<description><![CDATA[本文将简单介绍一些 BitTorrent 协议和一些术语，来让读者有一个整体的概念。]]></description>
										<content:encoded><![CDATA[
<h2 class="wp-block-heading">概述</h2>



<p class="wp-block-paragraph">本文将简单介绍一些 BitTorrent 协议和一些术语，来让读者有一个整体的概念。</p>



<h2 class="wp-block-heading">B 编码（bencoding）</h2>



<p class="wp-block-paragraph"> B 编码（bencoding）是用于编码协议消息的编码。Bittorrent 的许多协议中的消息都使用此种编码方式。此编码可以将字符串、整数、列表和字典编码成字符串。</p>



<p class="wp-block-paragraph">假设有一个字符串 <code>Hello World</code>，它会被编码为 <code>11:Hello World</code>。即 <code>长度:内容</code>。</p>



<p class="wp-block-paragraph">假设有一个整数 <code>256</code>，它会被编码为 <code>i:256e</code>。即开头是字母 <code>i</code>，后跟一个冒号 <code>:</code>，接着是十进制表示的数字，最后是一个字母 <code>e</code>。</p>



<p class="wp-block-paragraph">假设有一个列表 <code>[ 'spam', 'eggs' ]</code>，它会被编码成 <code>l4:spam4:eggse</code>。即以字母 <code>l</code> 开头，中间是列表的内容，并且内容也要使用对应的 B 编码进行编码，结尾一个字母 <code>e</code>。</p>



<p class="wp-block-paragraph">假设有一个字典 <code>{ 'cow': 'moo', 'spam': 'eggs'  }</code>，它会被编码成 <code>d3:cow3:moo4:spam4:eggse</code>。即以字母 <code>d</code> 开头，中间是内容，并且内容也要使用对应的 B 编码进行编码，结尾是一个字母 e。另一个例子是字典 <code>{ 'spam': [ 'a', 'b' ] }</code> 会被编码成 <code>d4:spaml1:a1:bee</code>。</p>



<h2 class="wp-block-heading">私有种子（Private Torrents）</h2>



<p class="wp-block-paragraph">一个种子（torrent）文件可以被标记为 ”私有的“，此时 BitTorrent 客户端应该禁用除了 Tracker 以外的所有 Peer 搜索方式，并且仅能使用私有的 Tracker。</p>



<h2 class="wp-block-heading">伙伴（Peer）协议</h2>



<p class="wp-block-paragraph">伙伴协议（Peer Protocol）也可以翻译为 “对等体协议” 或者 “同伴协议”，是用于与 Peer 通信以完成下载任务的协议。该协议底层可以使用 TCP 或者 μTP 传输。</p>



<h2 class="wp-block-heading">Tracker 协议</h2>



<p class="wp-block-paragraph"> Tracker 协议是用于发现伙伴（Peer）协议。</p>



<p class="wp-block-paragraph">有时我们并不知道哪些主机提供了我们需要的资源，这时你可以使用 Tracker 协议来获取这些信息，主机会使用 Tracker 协议来告知其它主机自己提供哪些资源，也可以使用 Tracker 协议得知某个资源被哪些主机提供。</p>



<h2 class="wp-block-heading">μTorrent 传输协议</h2>



<p class="wp-block-paragraph">BitTorrent 主机通常会开很多个连接来为许多个 Peer 服务。但是 TCP 会将带宽均匀地分配给每个连接，这就导致 BitTorrent 软件占用了大量的带宽，容易影响其它软件，特别是交互性强的软件如浏览器、游戏和聊天软件。</p>



<p class="wp-block-paragraph">μTorrent 传输协议是一个基于 UDP 的传输协议，它可以动态地调整带宽使用量，避免影响其它软件的网络通信。</p>



<h2 class="wp-block-heading">分布式散列表（Distributed sloppy Hash Table）协议</h2>



<p class="wp-block-paragraph">BitTorrent 网络本身是一个容错性十分高的网络，但其一大弱点就是 Tracker 服务器，因为一旦 Tracker 服务器下线，网络中的主机就无法联系到持有所需资源的主机。</p>



<p class="wp-block-paragraph">分布式散列表协议也称 DHT 协议，它可以让 BitTorrent 网络中的主机在不依赖 Tracker 服务器的情况下联系到持有所需资源的主机。</p>



<h2 class="wp-block-heading">伙伴交换（Peer Exchange）协议</h2>



<p class="wp-block-paragraph">伙伴交换（Peer Exchange）协议是让两个 Peer 互相交换对方的 Peer 的协议。其实就是两个朋友之间互相向对方介绍自己的朋友，这样大家的朋友就会越来越多。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.addesp.com/archives/5236/feed</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>从零设计通信协议（二）</title>
		<link>https://www.addesp.com/archives/4528</link>
					<comments>https://www.addesp.com/archives/4528#comments</comments>
		
		<dc:creator><![CDATA[ADD-SP]]></dc:creator>
		<pubDate>Mon, 24 May 2021 13:21:42 +0000</pubDate>
				<category><![CDATA[从零设计通信协议]]></category>
		<category><![CDATA[唯密文攻击]]></category>
		<category><![CDATA[网络安全]]></category>
		<category><![CDATA[通信协议]]></category>
		<guid isPermaLink="false">https://www.addesp.com/?p=4528</guid>

					<description><![CDATA[升级协议以抵御「唯密文攻击」。]]></description>
										<content:encoded><![CDATA[
<h2 class="wp-block-heading">写在前面</h2>



<ul class="wp-block-list"><li>本系列的介绍以及协议功能见「<a href="https://www.addesp.com/archives/4463">从零设计通信协议（一）</a>」。</li><li>本系列的全部文章见「<a href="https://www.addesp.com/archives/category/%e7%ac%94%e8%ae%b0/%e4%bb%8e%e9%9b%b6%e8%ae%be%e8%ae%a1%e9%80%9a%e4%bf%a1%e5%8d%8f%e8%ae%ae">从零设计通信协议系列</a>」。</li></ul>



<h2 class="wp-block-heading">上一版协议</h2>



<p class="wp-block-paragraph">首先回顾的以下上一版的协议。</p>



<figure class="wp-block-table aligncenter is-style-regular"><table class="has-fixed-layout"><thead><tr><th class="has-text-align-center" data-align="center">1 字节</th><th class="has-text-align-center" data-align="center">X 字节</th></tr></thead><tbody><tr><td class="has-text-align-center" data-align="center">数据长度</td><td class="has-text-align-center" data-align="center">数据</td></tr></tbody></table><figcaption>数据包格式</figcaption></figure>



<p class="wp-block-paragraph">整个数据包使用 AES-128-ECB 加密。</p>



<ul class="wp-block-list"><li>数据长度：表示「数据」的长度，单位为字节。</li><li>数据：表示具体的通信数据。</li></ul>



<p class="wp-block-paragraph">我们可以通过数据包的前一个字节获取数据长度，之后向后读取 X 字节即可获取全部的数据，整个数据包使用 AES-128-ECB 加密，看起来很安全。其实使用 AES-128-ECB 加密容易受到「唯密文攻击」。</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><p>唯密文攻击：指在仅知道密文的情况加进行攻击，攻击成功轻则获得部分或全部明文，重则获取密钥。</p><cite><a href="https://baike.baidu.com/item/%E5%94%AF%E5%AF%86%E6%96%87%E6%94%BB%E5%87%BB" target="_blank" rel="noreferrer noopener" title="https://baike.baidu.com/item/%E5%94%AF%E5%AF%86%E6%96%87%E6%94%BB%E5%87%BB">唯密文攻击_百度百科</a></cite></blockquote>



<h2 class="wp-block-heading">ECB 模式的缺陷</h2>



<p class="wp-block-paragraph">ECB 模式的缺陷就是相同的明文会产生相同的密文，这会让攻击者有机会猜出密文的含义，难以抵抗统计分析。</p>



<p class="wp-block-paragraph">例如我和 Alice 对话，每次我发送的第一个信息是「你好」，假设使用 ECB 模式加密后的密文为「#￥%#￥」，那么如果 Eve 中间截获我的数据包，发现我和 Alice 每次通信我都会先发一个「#￥%#￥」给 Alice。根据日常的对话习惯，Eve 猜测这可能是在打招呼，进而怀疑「#￥%#￥」解密后是「你好」、「有空么」之类的话，这已经十分接近我们的明文信息了。</p>



<p class="wp-block-paragraph">上面的例子可能并不特别可怕，但是如果进行统计分析的话就难说了。</p>



<h2 class="wp-block-heading">CBC 模式</h2>



<p class="wp-block-paragraph">CBC 即密码分组链接（<strong>C</strong>ipher-<strong>B</strong>lock <strong>C</strong>haining），我们无需关心原理，只需要知道该模式通过一个随机的初始化向量 <strong>IV</strong> 保证了每条消息的唯一性，即相同的明文可以对应许多个密文。</p>



<h2 class="wp-block-heading">第二版协议</h2>



<p class="wp-block-paragraph">下面我们使用 AES-128-CBC 算法来加密我们的通讯信息，使用 CBC 模式加密不仅需要密钥，也需要一个随机的初始化向量 <strong>IV</strong>，所以我们需要将 <strong>IV</strong> 传递给对方。</p>



<figure class="wp-block-table is-style-regular"><table class="has-fixed-layout"><thead><tr><th class="has-text-align-center" data-align="center">16 字节</th><th class="has-text-align-center" data-align="center">1 字节</th><th class="has-text-align-center" data-align="center">X 字节</th></tr></thead><tbody><tr><td class="has-text-align-center" data-align="center">IV</td><td class="has-text-align-center" data-align="center">数据长度</td><td class="has-text-align-center" data-align="center">数据</td></tr></tbody></table><figcaption>数据包格式</figcaption></figure>



<p class="wp-block-paragraph"><strong>数据包从第 17 个字节开始的所有数据要使用 AES-128-CBC 加密。</strong></p>



<ul class="wp-block-list"><li>IV：AES-128-CBC 加密时所用的初始化向量。</li><li>数据长度：表示「数据」的长度，单位为字节。</li><li>数据：表示具体的通信数据。</li></ul>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><p>初始化向量 <strong>IV</strong> 可以公开，但要保证不可预测。</p></blockquote>



<h2 class="wp-block-heading">写在最后</h2>



<p class="wp-block-paragraph">本次我们升级了协议，使得协议可以抵御「唯密文攻击」，本系列将会持续完善这一协议。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.addesp.com/archives/4528/feed</wfw:commentRss>
			<slash:comments>3</slash:comments>
		
		
			</item>
		<item>
		<title>从零设计通信协议（一）</title>
		<link>https://www.addesp.com/archives/4463</link>
					<comments>https://www.addesp.com/archives/4463#respond</comments>
		
		<dc:creator><![CDATA[ADD-SP]]></dc:creator>
		<pubDate>Mon, 24 May 2021 07:19:41 +0000</pubDate>
				<category><![CDATA[从零设计通信协议]]></category>
		<category><![CDATA[网络安全]]></category>
		<category><![CDATA[通信协议]]></category>
		<guid isPermaLink="false">https://www.addesp.com/?p=4463</guid>

					<description><![CDATA[逐步完善一个玩具性质的应用层通信协议。]]></description>
										<content:encoded><![CDATA[
<h2 class="wp-block-heading">写在前面</h2>



<p class="wp-block-paragraph">当你看到这个网页时你会知道 HTTPS 协议正在工作，你还知道这个协议能够抵御许多的网络攻击，保证通信安全。不过，我们知道的可能没有更多了。</p>



<p class="wp-block-paragraph">作为一个充满好奇心的沙雕，我希望自己搞一个玩具性质的应用层通信协议。所以本系列将会把我的设计过程记录在这里，本系列每次更新都会进行增强协议功能或修复安全性问题，你或许可以学习到一些知识，或许也可能找出我的一些错误。</p>



<h2 class="wp-block-heading">协议功能</h2>



<p class="wp-block-paragraph">为通信双方提供一个可靠的、有序的、安全的通信协议。要求通信双方预先共享足够强的密钥，并保证密钥不泄露。</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><p>我们假装 TLS 不存在。</p></blockquote>



<h2 class="wp-block-heading">有序和可靠</h2>



<p class="wp-block-paragraph">既然是应用层协议，那么应用层以下的协议自然是随便选的。TCP 协议就可以保证数据传输的有序和可靠，所以本协议使用 TCP 作为底层传输协议。</p>



<h2 class="wp-block-heading">安全</h2>



<p class="wp-block-paragraph">什么是安全呢？我们就暂时定义为通信内容不被泄露和篡改吧。</p>



<h2 class="wp-block-heading">第一版协议</h2>



<p class="wp-block-paragraph">目前我们的协议很简单，再加上已经预先共享了密钥，所以就先不加上握手机制了。所以现在要做的就是选择加密算法，随便从网上找找，就用 AES-128-ECB 吧。</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><p>AES-128-ECB：AES 表示高级加密标准（<strong>A</strong>dvanced <strong>E</strong>ncryption <strong>S</strong>tandard）；128 表示密钥长度为 128 bit；ECB 表示加密模式为电子密码本（<strong>E</strong>lectronic <strong>C</strong>ode<strong>B</strong>ook）。</p></blockquote>



<p class="wp-block-paragraph">选择好了加密算法，那么我们就开始设计我们数据包格式吧。</p>



<figure class="wp-block-table aligncenter is-style-regular"><table class="has-fixed-layout"><thead><tr><th class="has-text-align-center" data-align="center">1 字节</th><th class="has-text-align-center" data-align="center">X 字节</th></tr></thead><tbody><tr><td class="has-text-align-center" data-align="center">数据长度</td><td class="has-text-align-center" data-align="center">数据</td></tr></tbody></table><figcaption>数据包格式</figcaption></figure>



<p class="wp-block-paragraph">整个数据包使用 AES-128-ECB 加密。</p>



<ul class="wp-block-list"><li>数据长度：表示「数据」的长度，单位为字节。</li><li>数据：表示具体的通信数据。</li></ul>



<p class="wp-block-paragraph">这样只要任何一方将上面的数据包正确解密就可以获取通信的内容，也可以按照此格式给对方发送信息。</p>



<h2 class="wp-block-heading">写在最后</h2>



<p class="wp-block-paragraph">协议十分简陋，但是已经算是一个雏形了，本系列将会持续完善这一协议。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.addesp.com/archives/4463/feed</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
