-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathatom.xml
217 lines (212 loc) · 234 KB
/
atom.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<id>http://Varuxn.github.io</id>
<title>Varuxn</title>
<subtitle>目が離せません</subtitle>
<icon>http://varuxn.github.io/assets/favicon.ico</icon>
<link href="http://Varuxn.github.io" />
<author>
<name>Varuxn</name>
</author>
<updated>2024-12-22T07:35:42.447Z</updated>
<entry>
<id>http://varuxn.github.io/2024/12/22/WSL%E6%8D%A2%E8%A1%8C%E7%AC%A6/</id>
<title>Win11 下 WSL 换行符问题</title>
<link rel="alternate" href="http://varuxn.github.io/2024/12/22/WSL%E6%8D%A2%E8%A1%8C%E7%AC%A6/"/>
<content type="html"><h1 id="win11-下-wsl-换行符问题"><a class="anchor" href="#win11-下-wsl-换行符问题">#</a> Win11 下 WSL 换行符问题</h1>
<p>先说一下最终的解决方案:</p>
<h2 id="使用-wsl-强制创建-lf-格式文件"><a class="anchor" href="#使用-wsl-强制创建-lf-格式文件">#</a> 使用 WSL 强制创建 LF 格式文件</h2>
<p>在 WSL 环境中运行以下命令,确保文件始终以 LF 格式保存:</p>
<figure class="highlight bash"><figcaption data-lang="bash"></figcaption><table><tr><td data-num="1"></td><td><pre><span class="token builtin class-name">echo</span> <span class="token string">'export FILEFORMAT=unix'</span> <span class="token operator">>></span> ~/.bashrc</pre></td></tr><tr><td data-num="2"></td><td><pre><span class="token builtin class-name">source</span> ~/.bashrc</pre></td></tr></table></figure><p>操作完之后记得把之前的文件重新生成一遍。</p>
<h2 id="vscode-设置"><a class="anchor" href="#vscode-设置">#</a> VScode 设置</h2>
<p><strong>设置 -&gt; 用户设置 -&gt; 文本编辑器 -&gt; 文件 -&gt;eol</strong> 选项设置为 <code>\n</code></p>
<p>或者说只修改单个文件的话直接:</p>
<p>打开需要转换的文件,查看右下角状态栏的行尾符格式(CRLF 或 LF),点击行尾符,弹出选项框,选择 LF ,保存文件(Ctrl+S)。</p>
<h2 id="git-自动转换"><a class="anchor" href="#git-自动转换">#</a> Git 自动转换</h2>
<p>设置 Git 转换规则,配置 Git 仅在提交时将 CRLF 转换为 LF:</p>
<figure class="highlight bash"><figcaption data-lang="bash"></figcaption><table><tr><td data-num="1"></td><td><pre><span class="token function">git</span> config <span class="token parameter variable">--global</span> core.autocrlf input</pre></td></tr></table></figure><p>这会在提交时将行尾符转换为 LF,但保留工作区文件的 CRLF。</p>
<p>如果需要工作区文件也统一为 LF:</p>
<figure class="highlight bash"><figcaption data-lang="bash"></figcaption><table><tr><td data-num="1"></td><td><pre><span class="token function">git</span> config <span class="token parameter variable">--global</span> core.autocrlf <span class="token boolean">false</span></pre></td></tr></table></figure><p>然后重新克隆代码库或运行以下命令刷新文件:</p>
<figure class="highlight bash"><figcaption data-lang="bash"></figcaption><table><tr><td data-num="1"></td><td><pre><span class="token function">git</span> <span class="token function">rm</span> <span class="token parameter variable">--cached</span> <span class="token parameter variable">-r</span> <span class="token builtin class-name">.</span></pre></td></tr><tr><td data-num="2"></td><td><pre><span class="token function">git</span> reset <span class="token parameter variable">--hard</span></pre></td></tr></table></figure></content>
<updated>2024-12-22T07:35:42.447Z</updated>
</entry>
<entry>
<id>http://varuxn.github.io/2024/12/21/Hexo-ShokaX%E6%90%AD%E5%BB%BA%E7%AC%94%E8%AE%B0/</id>
<title>Hexo-ShokaX 搭建笔记</title>
<link rel="alternate" href="http://varuxn.github.io/2024/12/21/Hexo-ShokaX%E6%90%AD%E5%BB%BA%E7%AC%94%E8%AE%B0/"/>
<content type="html"><h1 id="hexo-shokax-搭建笔记"><a class="anchor" href="#hexo-shokax-搭建笔记">#</a> Hexo-ShokaX 搭建笔记</h1>
<p>shokax 主题是基于 shoka 主题的,所以很多东西要参照 shoka 的文档,一些问题也需要通过查找有关 shoka 的资料处理。</p>
<p>ShockX 的官方使用文档 <a href="https://docs-hexo.shokax.top/getting-started/">https://docs-hexo.shokax.top/getting-started/</a></p>
<p>更加详细的使用文档 <a href="https://docs.kaitaku.xyz/guide/theme.html">https://docs.kaitaku.xyz/guide/theme.html</a></p>
<p>基本上上面两个就足够解决大部分问题了</p>
<p>一些其他的博客:</p>
<p><a href="https://yuan-uyume.github.io/2023/08/26/zhibei/hexo%E4%B8%BB%E9%A2%98shokaX%E9%85%8D%E7%BD%AE%E8%B8%A9%E5%9D%91%E6%8C%87%E5%8C%97">https://yuan-uyume.github.io/2023/08/26/zhibei/hexo 主题 shokaX 配置踩坑指北</a></p>
<p>下面这篇博客是配置 shoka 主题的,他有关 package.json 的是不适用的,但是相关插件的安装还是可以借鉴的</p>
<p><a href="https://pigpigletsgo.github.io/hexo/shoka/%E9%85%8D%E7%BD%AEshoka%E4%B8%BB%E9%A2%98/">https://pigpigletsgo.github.io/hexo/shoka/ 配置 shoka 主题 /</a></p>
<h2 id="代码块渲染"><a class="anchor" href="#代码块渲染">#</a> 代码块渲染</h2>
<p>发现代码块还是最基础的,并没有采用 markdown-it 渲染,需要安装 <code>hexo-renderer-multi-markdown-it</code> 。</p>
<figure class="highlight bash"><figcaption data-lang="bash"></figcaption><table><tr><td data-num="1"></td><td><pre><span class="token function">pnpm</span> <span class="token function">install</span> hexo-renderer-multi-markdown-it</pre></td></tr></table></figure><h2 id="背景图片"><a class="anchor" href="#背景图片">#</a> 背景图片</h2>
<p>运行 <code>hexo s</code> 命令在本地看主页等图片是没有问题的但是向 github 上传之后出现了问题,我们可以参照使用文档里添加自己的背景图片</p>
<p>这就不得不提到图床了,以下是一个使用 PicGo 构建图床的方法的博客:</p>
<p><a href="https://blog.csdn.net/xdnxl/article/details/129466060">https://blog.csdn.net/xdnxl/article/details/129466060</a></p>
</content>
<updated>2024-12-21T15:23:00.822Z</updated>
</entry>
<entry>
<id>http://varuxn.github.io/2024/12/21/VMware-WSL/</id>
<title>关于 VMware 与 WSL 在 Win11 虚拟化的一些问题</title>
<link rel="alternate" href="http://varuxn.github.io/2024/12/21/VMware-WSL/"/>
<content type="html"><h1 id="关于-vmware-与-wsl-在-win11-虚拟化的一些问题"><a class="anchor" href="#关于-vmware-与-wsl-在-win11-虚拟化的一些问题">#</a> 关于 VMware 与 WSL 在 Win11 虚拟化的一些问题</h1>
<h2 id="vmware-虚拟化问题"><a class="anchor" href="#vmware-虚拟化问题">#</a> VMware 虚拟化问题</h2>
<p>之前用虚拟机做计网 GNS3 组网实验的时候需要用到虚拟机虚拟化,然后一直显示虚拟化不成功,检查过 BIOS 等设置均显示没有错误。</p>
<p>后来发现是 Windows 自带的虚拟机功能与 VMware 的虚拟化功能产生了冲突,处理办法如下:</p>
<p>有关 Intel-VX 的问题,首先是在 BIOS 里打开相关选项</p>
<p>然后 VMware 中也需要在设置里面开启</p>
<p>接下来就是关闭 Windows 自带的虚拟机功能 <strong>控制面板 -&gt; 程序 -&gt; 启用或关闭 Windows 功能</strong></p>
<p>Hyper-V 和 Windows 虚拟机监控程序平台取消勾选</p>
<p>如果找不到 Hyper-V 则管理员身份打开 powershell 输入命令 <code>bcdedit /set hypervisorlaunchtype off</code></p>
<p>最后重启电脑。</p>
<p>参照博客:<a href="https://blog.csdn.net/m0_53022813/article/details/136936036">https://blog.csdn.net/m0_53022813/article/details/136936036</a></p>
<h2 id="wsl-虚拟化问题"><a class="anchor" href="#wsl-虚拟化问题">#</a> WSL 虚拟化问题</h2>
<p>在 VMware 虚拟化问题前,配置过一次 ubuntu 的 WSL 运行起来也没问题,后来因为一些原因卸载了。</p>
<p>现在重新下回来的时候发现竟然又碰到了虚拟化的问题,然后就发现大概是上述 VMware 虚拟化关闭了本机一些虚拟化功能的问题。</p>
<p>解决办法如下:</p>
<p>打开 Windows 自带的虚拟机功能 <strong>控制面板 -&gt; 程序 -&gt; 启用或关闭 Windows 功能</strong></p>
<p>Hyper-V 和 Windows 虚拟机监控程序平台勾选</p>
<p>如果找不到 Hyper-V 则管理员身份打开 powershell 输入命令 <code>bcdedit /set hypervisorlaunchtype auto</code></p>
<p>最后重启电脑。</p>
<h2 id="后记"><a class="anchor" href="#后记">#</a> 后记</h2>
<p>我的是华硕天选 4 的笔记本,不知道其他的电脑会不会出现类似的问题。。。</p>
</content>
<updated>2024-12-21T12:47:19.650Z</updated>
</entry>
<entry>
<id>http://varuxn.github.io/2024/12/21/Visual%20Studio%20C++%20%E6%B1%87%E7%BC%96%20%E6%B7%B7%E5%90%88%E7%BC%96%E7%A8%8B/</id>
<title>Visual Studio C++ 汇编 混合编程</title>
<link rel="alternate" href="http://varuxn.github.io/2024/12/21/Visual%20Studio%20C++%20%E6%B1%87%E7%BC%96%20%E6%B7%B7%E5%90%88%E7%BC%96%E7%A8%8B/"/>
<content type="html"><h1 id="visual-studio-c-汇编-混合编程"><a class="anchor" href="#visual-studio-c-汇编-混合编程">#</a> Visual Studio C++ 汇编 混合编程</h1>
<h2 id="实验要求"><a class="anchor" href="#实验要求">#</a> 实验要求</h2>
<p>请用汇编语言编写实现 GCD 递推公式的子程序,对入口和出口参数形式不做要求,但需要用 C 语言函数来获取输入、调用汇编递推子程序,并且用 C 语言显示子程序返回的结果。</p>
<h2 id="visual-studio-2020-下载"><a class="anchor" href="#visual-studio-2020-下载">#</a> Visual Studio 2020 下载</h2>
<p>下载时勾选 C++ 桌面开发选项。</p>
<p><img loading="lazy" data-src="https://cdn.jsdelivr.net/gh/Varuxn/pictures-bed@master/img1.png" alt="" /></p>
<h2 id="环境配置"><a class="anchor" href="#环境配置">#</a> 环境配置</h2>
<p>选择 <strong>文件 -&gt; 新建 -&gt; 项目</strong> ,语言选择 <strong>C++</strong> ,选择 <strong>空项目</strong> 。</p>
<p><img loading="lazy" data-src="https://cdn.jsdelivr.net/gh/Varuxn/pictures-bed@master/img2.png" alt="" /></p>
<p>修改环境配置为 <strong>x86</strong>。</p>
<p><img loading="lazy" data-src="https://cdn.jsdelivr.net/gh/Varuxn/pictures-bed@master/img3.png" alt="" /></p>
<p>在项目中新建 <code>gcd.asm</code> 和 <code>t.cpp</code> 或将这两个文件添加到项目中。</p>
<p>右键项目,选择 <strong>生成依赖项 -&gt; 生成自定义</strong>,勾选 <strong>masm</strong> 选项。</p>
<p><img loading="lazy" data-src="https://cdn.jsdelivr.net/gh/Varuxn/pictures-bed@master/img4.png" alt="" /></p>
<p><img loading="lazy" data-src="https://cdn.jsdelivr.net/gh/Varuxn/pictures-bed@master/img5.png" alt="" /></p>
<p>右键 <code>gcd.asm</code> 文件,选择 <strong>属性</strong>。</p>
<p><strong>从生成中排除</strong> 选择 <strong>否</strong>。</p>
<p><strong>项类型</strong> 选择 <strong>Microsoft Macro Assembler</strong>。</p>
<p><img loading="lazy" data-src="https://cdn.jsdelivr.net/gh/Varuxn/pictures-bed@master/img6.png" alt="" /></p>
<p>在编译运行的时候出现如下错误:</p>
<p><code>scanf‘: This function or variable may be unsafe.Consider using scanf_s instead</code></p>
<p>相关问题的解答 <a href="https://blog.csdn.net/p3145417646/article/details/131686176">Link</a></p>
<p>可以在 <code>.cpp</code> 文件的头文件加入 <code>#define _CRT_SECURE_NO_WARNINGS</code> 。</p>
<h2 id="code"><a class="anchor" href="#code">#</a> Code</h2>
<p>cpp 文件</p>
<figure class="highlight cpp"><figcaption data-lang="C++"></figcaption><table><tr><td data-num="1"></td><td><pre><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">_CRT_SECURE_NO_WARNINGS</span></span></pre></td></tr><tr><td data-num="2"></td><td><pre><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;stdio.h></span></span></pre></td></tr><tr><td data-num="3"></td><td><pre></pre></td></tr><tr><td data-num="4"></td><td><pre><span class="token comment">// 声明外部汇编函数</span></pre></td></tr><tr><td data-num="5"></td><td><pre><span class="token keyword">extern</span> <span class="token string">"C"</span> <span class="token keyword">int</span> <span class="token function">GCD</span><span class="token punctuation">(</span><span class="token keyword">int</span> a<span class="token punctuation">,</span> <span class="token keyword">int</span> b<span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="6"></td><td><pre></pre></td></tr><tr><td data-num="7"></td><td><pre><span class="token keyword">int</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="8"></td><td><pre> <span class="token keyword">int</span> a<span class="token punctuation">,</span> b<span class="token punctuation">,</span> result<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="9"></td><td><pre></pre></td></tr><tr><td data-num="10"></td><td><pre> <span class="token comment">// 获取用户输入</span></pre></td></tr><tr><td data-num="11"></td><td><pre> <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"请输入两个整数以计算其最大公约数:"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="12"></td><td><pre> <span class="token function">scanf</span><span class="token punctuation">(</span><span class="token string">"%d %d"</span><span class="token punctuation">,</span> <span class="token operator">&amp;</span>a<span class="token punctuation">,</span> <span class="token operator">&amp;</span>b<span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="13"></td><td><pre></pre></td></tr><tr><td data-num="14"></td><td><pre> <span class="token comment">// 调用汇编函数</span></pre></td></tr><tr><td data-num="15"></td><td><pre> result <span class="token operator">=</span> <span class="token function">GCD</span><span class="token punctuation">(</span>a<span class="token punctuation">,</span> b<span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="16"></td><td><pre></pre></td></tr><tr><td data-num="17"></td><td><pre> <span class="token comment">// 输出结果</span></pre></td></tr><tr><td data-num="18"></td><td><pre> <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"数字 %d 和 %d 的最大公约数是:%d\n"</span><span class="token punctuation">,</span> a<span class="token punctuation">,</span> b<span class="token punctuation">,</span> result<span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="19"></td><td><pre></pre></td></tr><tr><td data-num="20"></td><td><pre> <span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="21"></td><td><pre><span class="token punctuation">&#125;</span></pre></td></tr></table></figure><p>asm 文件</p>
<pre><code class="language-asm">.model flat, c
.code
public GCD ; 声明函数为公共,可以被外部调用
GCD proc
mov eax, [esp+4] ; 获取第一个参数 a (位于 esp+4)
mov ebx, [esp+8] ; 获取第二个参数 b (位于 esp+8)
gcd_loop:
cmp ebx, 0 ; 如果 b == 0,跳转到结束
je gcd_done
xor edx, edx ; 清空 edx,避免余数计算时的干扰
div ebx ; eax = eax / ebx,余数存入 edx
mov eax, ebx ; a = b
mov ebx, edx ; b = a % b
jmp gcd_loop
gcd_done:
ret ; 返回结果存于 eax
GCD endp
end
</code></pre>
</content>
<updated>2024-12-21T12:46:38.153Z</updated>
</entry>
<entry>
<id>http://varuxn.github.io/2024/12/21/TFTP-Server/</id>
<title>HUST 计网 TFTP Server 实验总结</title>
<link rel="alternate" href="http://varuxn.github.io/2024/12/21/TFTP-Server/"/>
<content type="html"><h1 id="tftp-server-总结"><a class="anchor" href="#tftp-server-总结">#</a> TFTP Server 总结</h1>
<h2 id="前言"><a class="anchor" href="#前言">#</a> 前言</h2>
<p>其实我菜的要死,然后在各位大佬的帮助下勉强完成了任务,然后过来水一篇博客,算是记录一下,也可以看作是蹭流量哈哈哈哈,可能主要讲一讲配置的问题。</p>
<h2 id="前置环境"><a class="anchor" href="#前置环境">#</a> 前置环境</h2>
<p>也就是两个软件,Tftpd64 和 clumsy 以及在 Windows 环境下的编译问题。</p>
<p><img loading="lazy" data-src="https://images.cnblogs.com/cnblogs_com/Varuxn/2401763/o_241117145120_QQ20241117-225039.png" alt="" /></p>
<h3 id="tftpd64"><a class="anchor" href="#tftpd64">#</a> Tftpd64</h3>
<p>Tftpd64 的功能是当做 TFTP 通信中的客户端,各个参数的含义如下</p>
<figure class="highlight txt"><figcaption data-lang="txt"></figcaption><table><tr><td data-num="1"></td><td><pre>Host 127.0.0.1 即为本机地址</pre></td></tr><tr><td data-num="2"></td><td><pre>Port 69 一般是69,如果端口冲突也可以选择其他的,需要与服务器的 port 一致</pre></td></tr><tr><td data-num="3"></td><td><pre>Local File 选择的是想要从客户端传送到服务器的文件的地址,从服务器传过来的文件也会放在同一目录下。</pre></td></tr><tr><td data-num="4"></td><td><pre>Remote File 则是想要请求的文件的名称</pre></td></tr><tr><td data-num="5"></td><td><pre>Block Size 512 与实验要求的一致</pre></td></tr><tr><td data-num="6"></td><td><pre>Get 就是从服务器索要文件</pre></td></tr><tr><td data-num="7"></td><td><pre>Put 就是将文件传送给服务器</pre></td></tr></table></figure><p><img loading="lazy" data-src="https://images.cnblogs.com/cnblogs_com/Varuxn/2401763/o_241117145302_tftp.png" alt="" /></p>
<h3 id="clumsy"><a class="anchor" href="#clumsy">#</a> clumsy</h3>
<p>clumsy 则是模拟传输过程的错误的软件。</p>
<p>值得的一提的是,在调试代码的时候一直开着这个软件的丢包,导致我开着 VPN 却用不了 GPT,甚至使用 Baidu/Google 都困难。用网易云听歌也是有电流声,一开始还怀疑是耳机的问题哈哈哈。</p>
<p>各个参数在文档中已经声明了</p>
<figure class="highlight txt"><figcaption data-lang="txt"></figcaption><table><tr><td data-num="1"></td><td><pre>延迟(Lag),把数据包缓存一段时间后再发出,这样能够模拟网络延迟的状况。</pre></td></tr><tr><td data-num="2"></td><td><pre>掉包(Drop),随机丢弃一些数据。</pre></td></tr><tr><td data-num="3"></td><td><pre>节流(Throttle),把一小段时间内的数据拦截下来后再在之后的同一时间一同发出去。</pre></td></tr><tr><td data-num="4"></td><td><pre>重发(Duplicate),随机复制一些数据并与其本身一同发送。</pre></td></tr><tr><td data-num="5"></td><td><pre>乱序(Out of order),打乱数据包发送的顺序。</pre></td></tr><tr><td data-num="6"></td><td><pre>篡改(Tamper),随机修改小部分的包裹内容。</pre></td></tr></table></figure><p>运行起来大概是下图这个样子,测试的时候用哪个就把哪个勾上然后 start 就可以了</p>
<p><img loading="lazy" data-src="https://images.cnblogs.com/cnblogs_com/Varuxn/2401763/o_241117150143_QQ20241117-230131.png" alt="" /></p>
<h3 id="编译问题"><a class="anchor" href="#编译问题">#</a> 编译问题</h3>
<p>老师应该是下发一个 client 的 .c 文件的,但是大家会发现无法运行,因为老师下发的软件是需要在 linux 环境下运行。如果想要在 Win11 环境下运行需要更改一些头文件,然后代码里有些东西需要修改,这些内容不太重要,不如直接在下文讨论在写 Server 文件时该注意什么。</p>
<h2 id="代码书写"><a class="anchor" href="#代码书写">#</a> 代码书写</h2>
<p>首先需要声明我的代码的文件是写到了 <code>t.cpp</code> 当中,编译的话使用的命令是 <code>g++ t.cpp -o tftp_server -lws2_32</code> ,会生成一个 <code>tftp_server.exe</code> 文件,直接运行就可以得到客户端,很遗憾本人菜菜没有做可视化界面 /kel。</p>
<p>代码的书写参照了 <a href="https://doraemonqwq.cn/2024/10/07/2024-10-7-network/">灰灰的博客</a>,并且对某些部分做了自己的一些修改。</p>
<h3 id="一些定义以及调用"><a class="anchor" href="#一些定义以及调用">#</a> 一些定义以及调用</h3>
<p>一些用到的库,还有一些常量的声明,格外需要注意 <code>#pragma comment(lib, &quot;ws2_32.lib&quot;)</code> 命令,这个命令在 Windows 中是必须的,其中 IP 写成自己主机的 IP。</p>
<figure class="highlight cpp"><figcaption data-lang="C++"></figcaption><table><tr><td data-num="1"></td><td><pre><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;WinSock2.h></span></span></pre></td></tr><tr><td data-num="2"></td><td><pre><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;cstdio></span></span></pre></td></tr><tr><td data-num="3"></td><td><pre><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;psdk_inc/_ip_types.h></span></span></pre></td></tr><tr><td data-num="4"></td><td><pre><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;psdk_inc/_socket_types.h></span></span></pre></td></tr><tr><td data-num="5"></td><td><pre><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;stdlib.h></span></span></pre></td></tr><tr><td data-num="6"></td><td><pre><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;wingdi.h></span></span></pre></td></tr><tr><td data-num="7"></td><td><pre><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;winsock2.h></span></span></pre></td></tr><tr><td data-num="8"></td><td><pre><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;ws2tcpip.h></span></span></pre></td></tr><tr><td data-num="9"></td><td><pre><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;windows.h></span></span></pre></td></tr><tr><td data-num="10"></td><td><pre><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;bits/stdc++.h></span></span></pre></td></tr><tr><td data-num="11"></td><td><pre></pre></td></tr><tr><td data-num="12"></td><td><pre><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">pragma</span> <span class="token expression"><span class="token function">comment</span><span class="token punctuation">(</span>lib<span class="token punctuation">,</span> </span><span class="token string">"ws2_32.lib"</span><span class="token expression"><span class="token punctuation">)</span></span></span></pre></td></tr><tr><td data-num="13"></td><td><pre></pre></td></tr><tr><td data-num="14"></td><td><pre><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">BUF_SIZE</span> <span class="token expression"><span class="token number">516</span></span></span></pre></td></tr><tr><td data-num="15"></td><td><pre><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">DATA_SIZE</span> <span class="token expression"><span class="token number">512</span></span></span></pre></td></tr><tr><td data-num="16"></td><td><pre><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">OPCODE_RRQ</span> <span class="token expression"><span class="token number">1</span></span></span></pre></td></tr><tr><td data-num="17"></td><td><pre><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">OPCODE_WRQ</span> <span class="token expression"><span class="token number">2</span></span></span></pre></td></tr><tr><td data-num="18"></td><td><pre><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">OPCODE_DATA</span> <span class="token expression"><span class="token number">3</span></span></span></pre></td></tr><tr><td data-num="19"></td><td><pre><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">OPCODE_ACK</span> <span class="token expression"><span class="token number">4</span></span></span></pre></td></tr><tr><td data-num="20"></td><td><pre><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">OPCODE_ERROR</span> <span class="token expression"><span class="token number">5</span></span></span></pre></td></tr><tr><td data-num="21"></td><td><pre><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">MAX_RETRIES</span> <span class="token expression"><span class="token number">10</span></span></span></pre></td></tr><tr><td data-num="22"></td><td><pre><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">TIMEOUT</span> <span class="token expression"><span class="token number">5</span></span></span></pre></td></tr><tr><td data-num="23"></td><td><pre></pre></td></tr><tr><td data-num="24"></td><td><pre><span class="token keyword">static</span> <span class="token keyword">const</span> <span class="token keyword">char</span> <span class="token operator">*</span>tftp_error_msg<span class="token punctuation">[</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="25"></td><td><pre> <span class="token string">"Undefined error"</span><span class="token punctuation">,</span></pre></td></tr><tr><td data-num="26"></td><td><pre> <span class="token string">"File not found"</span><span class="token punctuation">,</span></pre></td></tr><tr><td data-num="27"></td><td><pre> <span class="token string">"Access violation"</span><span class="token punctuation">,</span></pre></td></tr><tr><td data-num="28"></td><td><pre> <span class="token string">"Disk full or allocation error"</span><span class="token punctuation">,</span></pre></td></tr><tr><td data-num="29"></td><td><pre> <span class="token string">"Illegal TFTP operation"</span><span class="token punctuation">,</span></pre></td></tr><tr><td data-num="30"></td><td><pre> <span class="token string">"Unknown transfer ID"</span><span class="token punctuation">,</span></pre></td></tr><tr><td data-num="31"></td><td><pre> <span class="token string">"File already exists"</span><span class="token punctuation">,</span></pre></td></tr><tr><td data-num="32"></td><td><pre> <span class="token string">"No such user"</span></pre></td></tr><tr><td data-num="33"></td><td><pre><span class="token punctuation">&#125;</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="34"></td><td><pre><span class="token keyword">const</span> <span class="token keyword">char</span> IP<span class="token punctuation">[</span><span class="token number">30</span><span class="token punctuation">]</span><span class="token operator">=</span><span class="token string">""</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="35"></td><td><pre><span class="token keyword">const</span> <span class="token keyword">int</span> PORT<span class="token operator">=</span><span class="token number">6699</span><span class="token punctuation">;</span></pre></td></tr></table></figure><h3 id="tftp的初始化"><a class="anchor" href="#tftp的初始化">#</a> TFTP 的初始化</h3>
<p>下面这段代码也是 Windows 环境下不同于 Linux 的部分。</p>
<figure class="highlight cpp"><figcaption data-lang="C++"></figcaption><table><tr><td data-num="1"></td><td><pre><span class="token keyword">int</span> <span class="token function">TFTP_init</span><span class="token punctuation">(</span><span class="token punctuation">)</span></pre></td></tr><tr><td data-num="2"></td><td><pre><span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="3"></td><td><pre> WSADATA wsaData<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="4"></td><td><pre> <span class="token keyword">int</span> result <span class="token operator">=</span> <span class="token function">WSAStartup</span><span class="token punctuation">(</span><span class="token function">MAKEWORD</span><span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token operator">&amp;</span>wsaData<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 初始化 Winsock</span></pre></td></tr><tr><td data-num="5"></td><td><pre> <span class="token keyword">if</span> <span class="token punctuation">(</span>result <span class="token operator">!=</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="6"></td><td><pre> cerr<span class="token operator">&lt;&lt;</span><span class="token string">"WSAStartup failed: "</span><span class="token operator">&lt;&lt;</span>result<span class="token operator">&lt;&lt;</span>endl<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="7"></td><td><pre> <span class="token keyword">return</span> <span class="token number">1</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="8"></td><td><pre> <span class="token punctuation">&#125;</span></pre></td></tr><tr><td data-num="9"></td><td><pre> <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"Winsock initialized.\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="10"></td><td><pre> <span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="11"></td><td><pre><span class="token punctuation">&#125;</span></pre></td></tr></table></figure><p>然后就是根据服务器的地址和接口绑定套接字(这段内容在代码的 Server 类的 init 部分),然后就是不断循环接收来自客户端的请求(Server 类的 work 部分)。</p>
<p>TFTP_Solve 类则是对于客户端的每个请求进行分类处理,而 ERRORthings 则是对错误信息进行处理后发送给客户端。接下来重点介绍 RRQ 和 WRQ 类。</p>
<p>由于实验有个要求是需要记录传输数据的速度,为此设计了一个 <code>gettimeofday</code> 函数用来记录每次传输的起始和截止时间用于计算速度。</p>
<h3 id="rrq"><a class="anchor" href="#rrq">#</a> RRQ</h3>
<p>首先需要知道的是,我们将一个文件分成了若干块,每块的大小是 512bytes ,不断循环读取文件直到读入的字符数小于 512 。</p>
<p>先将操作码和块的编号写到首部</p>
<figure class="highlight cpp"><figcaption data-lang="C++"></figcaption><table><tr><td data-num="1"></td><td><pre><span class="token function">memset</span><span class="token punctuation">(</span>data_pac<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> BUF_SIZE<span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="2"></td><td><pre><span class="token operator">*</span><span class="token punctuation">(</span><span class="token keyword">unsigned</span> <span class="token keyword">short</span><span class="token operator">*</span><span class="token punctuation">)</span>data_pac <span class="token operator">=</span> <span class="token function">htons</span><span class="token punctuation">(</span>OPCODE_DATA<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 操作码:数据包</span></pre></td></tr><tr><td data-num="3"></td><td><pre><span class="token operator">*</span><span class="token punctuation">(</span><span class="token keyword">unsigned</span> <span class="token keyword">short</span><span class="token operator">*</span><span class="token punctuation">)</span><span class="token punctuation">(</span>data_pac <span class="token operator">+</span> <span class="token number">2</span><span class="token punctuation">)</span> <span class="token operator">=</span> <span class="token function">htons</span><span class="token punctuation">(</span>block<span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr></table></figure><p>然后开始读入文件中的信息,并且处理错误信息,接下来就是传输,只要没有收到确认包或者说重传的次数小于我们要求的最大重传次数时则重传。 <code>while(!ack&amp;&amp;tot_retry&lt;MAX_RETRIES)</code></p>
<p>使用 sendto 函数发送当前块到客户端</p>
<figure class="highlight cpp"><figcaption data-lang="C++"></figcaption><table><tr><td data-num="1"></td><td><pre><span class="token function">sendto</span><span class="token punctuation">(</span>socketfd<span class="token punctuation">,</span> data_pac<span class="token punctuation">,</span> bytes_read <span class="token operator">+</span> <span class="token number">4</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token punctuation">(</span>sockaddr<span class="token operator">*</span><span class="token punctuation">)</span><span class="token operator">&amp;</span>client_addr<span class="token punctuation">,</span> client_addr_len<span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr></table></figure><p>然后使用 select 函数检测</p>
<figure class="highlight cpp"><figcaption data-lang="C++"></figcaption><table><tr><td data-num="1"></td><td><pre><span class="token keyword">int</span> select_result <span class="token operator">=</span> <span class="token function">select</span><span class="token punctuation">(</span>socketfd <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token operator">&amp;</span>read_fds<span class="token punctuation">,</span> <span class="token constant">NULL</span><span class="token punctuation">,</span> <span class="token constant">NULL</span><span class="token punctuation">,</span> <span class="token operator">&amp;</span>tv<span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr></table></figure><p>检查是否传输的数据有差错,并对错误类型进行分类处理决定是否重传和返回怎样的错误信息。如果 select 函数没有发现错误则使用 recvfrom 函数接收来自客户端的 ACK 包并进行检查判断。</p>
<figure class="highlight cpp"><figcaption data-lang="C++"></figcaption><table><tr><td data-num="1"></td><td><pre>recv_len<span class="token operator">=</span><span class="token function">recvfrom</span><span class="token punctuation">(</span>socketfd<span class="token punctuation">,</span>buf<span class="token punctuation">,</span>BUF_SIZE<span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token punctuation">(</span>sockaddr<span class="token operator">*</span><span class="token punctuation">)</span><span class="token operator">&amp;</span>client_addr<span class="token punctuation">,</span><span class="token operator">&amp;</span>client_addr_len<span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr></table></figure><p>最后计算传输速率即可。</p>
<h3 id="wrq"><a class="anchor" href="#wrq">#</a> WRQ</h3>
<p>虽然是师从灰灰,但是也对一部分进行了修改和优化,也就是 WRQ 这一部分。灰灰的代码在这一部分,面对丢包和篡改的情况往往会发生服务器不断读取来自客户端的同一个 block 的数据,陷入死循环,一直将客户端某个 block 的数据写入目的文件。在调试后发现问题出现在 Server 在把选择新的块的时候并没有考虑客户端是否收到了 ACK 并且向下一个 block 移动,而是仅仅将 block++,对相关部分我们需要做出修改。</p>
<p>依旧是在确定文件的指针无误后进入循环,一块块地接收数据,先将上一个包的 ACK 发送给客户端,然后接受数据包。</p>
<p>在此处我们设置两个变量 <code>received_block</code> 和 <code>expected_block</code> ,分别表示我们接受到的 block 编号和我们期望收到的 block 编号。如果两者一致的话则表明我们的数据传输没有任何问题,直接写入文件,并且期望下一个 block 。</p>
<figure class="highlight cpp"><figcaption data-lang="C++"></figcaption><table><tr><td data-num="1"></td><td><pre><span class="token keyword">if</span> <span class="token punctuation">(</span>received_block <span class="token operator">==</span> expected_block<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="2"></td><td><pre> <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"Received block NO.%hu\n"</span><span class="token punctuation">,</span> received_block<span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="3"></td><td><pre> tot_recv <span class="token operator">+=</span> recv_len <span class="token operator">-</span> <span class="token number">4</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="4"></td><td><pre> <span class="token function">fwrite</span><span class="token punctuation">(</span>buf <span class="token operator">+</span> <span class="token number">4</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">,</span> recv_len <span class="token operator">-</span> <span class="token number">4</span><span class="token punctuation">,</span> file<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 写入文件</span></pre></td></tr><tr><td data-num="5"></td><td><pre> expected_block<span class="token operator">++</span><span class="token punctuation">;</span> <span class="token comment">// 仅在收到正确的数据包时递增</span></pre></td></tr><tr><td data-num="6"></td><td><pre><span class="token punctuation">&#125;</span></pre></td></tr></table></figure><p>否则的话输出错误提示信息并且尝试再次发送 ACK 包以及接受数据,直到收到的 block 编号和期望的一致。</p>
<p>最后就是统计传输速率以及发送最后一个块的 ACK 给客户端。</p>
<h2 id="code"><a class="anchor" href="#code">#</a> code</h2>
<p>本 blog 只讲述了一种最简单的实现方法(而且还没验收),需要代码详细解释的请移步灰灰的博客请教师祖大人捏。可视化的俺也没做,俺是菜狗。</p>
<figure class="highlight cpp"><figcaption data-lang="C++"></figcaption><table><tr><td data-num="1"></td><td><pre><span class="token comment">//g++ t.cpp -o tftp_server -lws2_32</span></pre></td></tr><tr><td data-num="2"></td><td><pre><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;WinSock2.h></span></span></pre></td></tr><tr><td data-num="3"></td><td><pre><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;cstdio></span></span></pre></td></tr><tr><td data-num="4"></td><td><pre><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;psdk_inc/_ip_types.h></span></span></pre></td></tr><tr><td data-num="5"></td><td><pre><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;psdk_inc/_socket_types.h></span></span></pre></td></tr><tr><td data-num="6"></td><td><pre><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;stdlib.h></span></span></pre></td></tr><tr><td data-num="7"></td><td><pre><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;wingdi.h></span></span></pre></td></tr><tr><td data-num="8"></td><td><pre><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;winsock2.h></span></span></pre></td></tr><tr><td data-num="9"></td><td><pre><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;ws2tcpip.h></span></span></pre></td></tr><tr><td data-num="10"></td><td><pre><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;windows.h></span></span></pre></td></tr><tr><td data-num="11"></td><td><pre><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;bits/stdc++.h></span></span></pre></td></tr><tr><td data-num="12"></td><td><pre></pre></td></tr><tr><td data-num="13"></td><td><pre><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">pragma</span> <span class="token expression"><span class="token function">comment</span><span class="token punctuation">(</span>lib<span class="token punctuation">,</span> </span><span class="token string">"ws2_32.lib"</span><span class="token expression"><span class="token punctuation">)</span></span></span></pre></td></tr><tr><td data-num="14"></td><td><pre></pre></td></tr><tr><td data-num="15"></td><td><pre><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">BUF_SIZE</span> <span class="token expression"><span class="token number">516</span></span></span></pre></td></tr><tr><td data-num="16"></td><td><pre><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">DATA_SIZE</span> <span class="token expression"><span class="token number">512</span></span></span></pre></td></tr><tr><td data-num="17"></td><td><pre><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">OPCODE_RRQ</span> <span class="token expression"><span class="token number">1</span></span></span></pre></td></tr><tr><td data-num="18"></td><td><pre><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">OPCODE_WRQ</span> <span class="token expression"><span class="token number">2</span></span></span></pre></td></tr><tr><td data-num="19"></td><td><pre><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">OPCODE_DATA</span> <span class="token expression"><span class="token number">3</span></span></span></pre></td></tr><tr><td data-num="20"></td><td><pre><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">OPCODE_ACK</span> <span class="token expression"><span class="token number">4</span></span></span></pre></td></tr><tr><td data-num="21"></td><td><pre><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">OPCODE_ERROR</span> <span class="token expression"><span class="token number">5</span></span></span></pre></td></tr><tr><td data-num="22"></td><td><pre><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">MAX_RETRIES</span> <span class="token expression"><span class="token number">10</span></span></span></pre></td></tr><tr><td data-num="23"></td><td><pre><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">TIMEOUT</span> <span class="token expression"><span class="token number">5</span></span></span></pre></td></tr><tr><td data-num="24"></td><td><pre></pre></td></tr><tr><td data-num="25"></td><td><pre><span class="token keyword">using</span> <span class="token keyword">namespace</span> std<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="26"></td><td><pre></pre></td></tr><tr><td data-num="27"></td><td><pre><span class="token keyword">static</span> <span class="token keyword">const</span> <span class="token keyword">char</span> <span class="token operator">*</span>tftp_error_msg<span class="token punctuation">[</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="28"></td><td><pre> <span class="token string">"Undefined error"</span><span class="token punctuation">,</span></pre></td></tr><tr><td data-num="29"></td><td><pre> <span class="token string">"File not found"</span><span class="token punctuation">,</span></pre></td></tr><tr><td data-num="30"></td><td><pre> <span class="token string">"Access violation"</span><span class="token punctuation">,</span></pre></td></tr><tr><td data-num="31"></td><td><pre> <span class="token string">"Disk full or allocation error"</span><span class="token punctuation">,</span></pre></td></tr><tr><td data-num="32"></td><td><pre> <span class="token string">"Illegal TFTP operation"</span><span class="token punctuation">,</span></pre></td></tr><tr><td data-num="33"></td><td><pre> <span class="token string">"Unknown transfer ID"</span><span class="token punctuation">,</span></pre></td></tr><tr><td data-num="34"></td><td><pre> <span class="token string">"File already exists"</span><span class="token punctuation">,</span></pre></td></tr><tr><td data-num="35"></td><td><pre> <span class="token string">"No such user"</span></pre></td></tr><tr><td data-num="36"></td><td><pre><span class="token punctuation">&#125;</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="37"></td><td><pre><span class="token keyword">const</span> <span class="token keyword">char</span> IP<span class="token punctuation">[</span><span class="token number">30</span><span class="token punctuation">]</span><span class="token operator">=</span><span class="token string">"0.0.0.0"</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="38"></td><td><pre><span class="token keyword">const</span> <span class="token keyword">int</span> PORT<span class="token operator">=</span><span class="token number">6699</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="39"></td><td><pre><span class="token keyword">int</span> client_addr_len<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="40"></td><td><pre></pre></td></tr><tr><td data-num="41"></td><td><pre><span class="token keyword">void</span> <span class="token function">record</span><span class="token punctuation">(</span><span class="token keyword">char</span> <span class="token operator">*</span>ch<span class="token punctuation">)</span></pre></td></tr><tr><td data-num="42"></td><td><pre><span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="43"></td><td><pre> FILE <span class="token operator">*</span>file<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="44"></td><td><pre> file<span class="token operator">=</span><span class="token function">fopen</span><span class="token punctuation">(</span><span class="token string">"record_log"</span><span class="token punctuation">,</span><span class="token string">"w"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="45"></td><td><pre> <span class="token function">fwrite</span><span class="token punctuation">(</span>ch<span class="token punctuation">,</span><span class="token number">1</span><span class="token punctuation">,</span><span class="token function">strlen</span><span class="token punctuation">(</span>ch<span class="token punctuation">)</span><span class="token punctuation">,</span>file<span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="46"></td><td><pre><span class="token punctuation">&#125;</span></pre></td></tr><tr><td data-num="47"></td><td><pre></pre></td></tr><tr><td data-num="48"></td><td><pre><span class="token keyword">int</span> <span class="token function">gettimeofday</span><span class="token punctuation">(</span><span class="token keyword">struct</span> <span class="token class-name">timeval</span><span class="token operator">*</span> tp<span class="token punctuation">,</span> <span class="token keyword">struct</span> <span class="token class-name">timezone</span><span class="token operator">*</span> tzp<span class="token punctuation">)</span></pre></td></tr><tr><td data-num="49"></td><td><pre><span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="50"></td><td><pre> <span class="token keyword">if</span> <span class="token punctuation">(</span>tp <span class="token operator">==</span> <span class="token keyword">nullptr</span><span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="51"></td><td><pre></pre></td></tr><tr><td data-num="52"></td><td><pre> <span class="token keyword">struct</span> <span class="token class-name">_timeb</span> timebuffer<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="53"></td><td><pre> <span class="token function">_ftime</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>timebuffer<span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="54"></td><td><pre></pre></td></tr><tr><td data-num="55"></td><td><pre> tp<span class="token operator">-></span>tv_sec <span class="token operator">=</span> <span class="token generic-function"><span class="token function">static_cast</span><span class="token generic class-name"><span class="token operator">&lt;</span><span class="token keyword">long</span><span class="token operator">></span></span></span><span class="token punctuation">(</span>timebuffer<span class="token punctuation">.</span>time<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 秒部分</span></pre></td></tr><tr><td data-num="56"></td><td><pre> tp<span class="token operator">-></span>tv_usec <span class="token operator">=</span> timebuffer<span class="token punctuation">.</span>millitm <span class="token operator">*</span> <span class="token number">1000</span><span class="token punctuation">;</span> <span class="token comment">// 将毫秒转换为微秒</span></pre></td></tr><tr><td data-num="57"></td><td><pre></pre></td></tr><tr><td data-num="58"></td><td><pre> <span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="59"></td><td><pre><span class="token punctuation">&#125;</span></pre></td></tr><tr><td data-num="60"></td><td><pre></pre></td></tr><tr><td data-num="61"></td><td><pre><span class="token keyword">struct</span> <span class="token class-name">ERRORthings</span></pre></td></tr><tr><td data-num="62"></td><td><pre><span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="63"></td><td><pre> <span class="token keyword">short</span> opcode<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="64"></td><td><pre> <span class="token keyword">short</span> error_code<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="65"></td><td><pre> <span class="token keyword">char</span> message<span class="token punctuation">[</span>BUF_SIZE<span class="token punctuation">]</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="66"></td><td><pre> <span class="token keyword">void</span> <span class="token function">init</span><span class="token punctuation">(</span><span class="token keyword">short</span> _error_code<span class="token punctuation">,</span><span class="token keyword">const</span> <span class="token keyword">char</span><span class="token operator">*</span> _message<span class="token punctuation">)</span></pre></td></tr><tr><td data-num="67"></td><td><pre> <span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="68"></td><td><pre> opcode <span class="token operator">=</span> <span class="token number">5</span><span class="token punctuation">;</span> </pre></td></tr><tr><td data-num="69"></td><td><pre> error_code <span class="token operator">=</span> _error_code<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="70"></td><td><pre> <span class="token function">strcpy</span><span class="token punctuation">(</span>message<span class="token operator">+</span><span class="token number">4</span><span class="token punctuation">,</span> _message<span class="token punctuation">)</span><span class="token punctuation">;</span> </pre></td></tr><tr><td data-num="71"></td><td><pre> <span class="token punctuation">&#125;</span></pre></td></tr><tr><td data-num="72"></td><td><pre> <span class="token keyword">void</span> <span class="token function">work</span><span class="token punctuation">(</span><span class="token keyword">int</span> socketfd<span class="token punctuation">,</span> sockaddr_in <span class="token operator">&amp;</span>client_addr<span class="token punctuation">)</span></pre></td></tr><tr><td data-num="73"></td><td><pre> <span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="74"></td><td><pre> <span class="token function">memset</span><span class="token punctuation">(</span>message<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> BUF_SIZE<span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="75"></td><td><pre> <span class="token operator">*</span><span class="token punctuation">(</span><span class="token keyword">unsigned</span> <span class="token keyword">short</span><span class="token operator">*</span><span class="token punctuation">)</span>message <span class="token operator">=</span> <span class="token function">htons</span><span class="token punctuation">(</span>opcode<span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="76"></td><td><pre> <span class="token operator">*</span><span class="token punctuation">(</span><span class="token keyword">unsigned</span> <span class="token keyword">short</span><span class="token operator">*</span><span class="token punctuation">)</span><span class="token punctuation">(</span>message <span class="token operator">+</span> <span class="token number">2</span><span class="token punctuation">)</span> <span class="token operator">=</span> <span class="token function">htons</span><span class="token punctuation">(</span>error_code<span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="77"></td><td><pre> <span class="token keyword">int</span> packet_length <span class="token operator">=</span> <span class="token number">4</span> <span class="token operator">+</span> <span class="token function">strlen</span><span class="token punctuation">(</span>message<span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="78"></td><td><pre> <span class="token keyword">int</span> send_len <span class="token operator">=</span> <span class="token function">sendto</span><span class="token punctuation">(</span>socketfd<span class="token punctuation">,</span> message<span class="token punctuation">,</span> packet_length<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token punctuation">(</span>sockaddr <span class="token operator">*</span><span class="token punctuation">)</span><span class="token operator">&amp;</span>client_addr<span class="token punctuation">,</span> client_addr_len<span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="79"></td><td><pre> <span class="token punctuation">&#125;</span></pre></td></tr><tr><td data-num="80"></td><td><pre><span class="token punctuation">&#125;</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="81"></td><td><pre></pre></td></tr><tr><td data-num="82"></td><td><pre><span class="token keyword">class</span> <span class="token class-name">RRQ</span></pre></td></tr><tr><td data-num="83"></td><td><pre><span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="84"></td><td><pre> <span class="token keyword">public</span><span class="token operator">:</span></pre></td></tr><tr><td data-num="85"></td><td><pre> <span class="token keyword">void</span> <span class="token function">work</span><span class="token punctuation">(</span><span class="token keyword">const</span> <span class="token keyword">char</span> <span class="token operator">*</span>filename<span class="token punctuation">,</span> <span class="token keyword">const</span> <span class="token keyword">char</span> <span class="token operator">*</span>mode<span class="token punctuation">,</span> <span class="token keyword">int</span> socketfd<span class="token punctuation">,</span> <span class="token keyword">struct</span> <span class="token class-name">sockaddr_in</span> <span class="token operator">&amp;</span>client_addr<span class="token punctuation">)</span></pre></td></tr><tr><td data-num="86"></td><td><pre> <span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="87"></td><td><pre> FILE <span class="token operator">*</span>file<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="88"></td><td><pre> <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token function">strcmp</span><span class="token punctuation">(</span>mode<span class="token punctuation">,</span><span class="token string">"netascii"</span><span class="token punctuation">)</span><span class="token operator">==</span><span class="token number">0</span><span class="token punctuation">)</span></pre></td></tr><tr><td data-num="89"></td><td><pre> file<span class="token operator">=</span><span class="token function">fopen</span><span class="token punctuation">(</span>filename<span class="token punctuation">,</span><span class="token string">"r"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="90"></td><td><pre> <span class="token keyword">else</span> file<span class="token operator">=</span><span class="token function">fopen</span><span class="token punctuation">(</span>filename<span class="token punctuation">,</span><span class="token string">"rb"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="91"></td><td><pre> <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token operator">!</span>file<span class="token punctuation">)</span></pre></td></tr><tr><td data-num="92"></td><td><pre> <span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="93"></td><td><pre> cerr<span class="token operator">&lt;&lt;</span><span class="token string">"ERROR: Cannot open file for reading: "</span><span class="token operator">&lt;&lt;</span>filename<span class="token operator">&lt;&lt;</span>endl<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="94"></td><td><pre> ERRORthings packet<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="95"></td><td><pre> packet<span class="token punctuation">.</span><span class="token function">init</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span>tftp_error_msg<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="96"></td><td><pre> packet<span class="token punctuation">.</span><span class="token function">work</span><span class="token punctuation">(</span>socketfd<span class="token punctuation">,</span> client_addr<span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="97"></td><td><pre> <span class="token keyword">return</span> <span class="token punctuation">;</span></pre></td></tr><tr><td data-num="98"></td><td><pre> <span class="token punctuation">&#125;</span></pre></td></tr><tr><td data-num="99"></td><td><pre> <span class="token keyword">unsigned</span> <span class="token keyword">short</span> block<span class="token operator">=</span><span class="token number">1</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="100"></td><td><pre> <span class="token keyword">int</span> bytes_read<span class="token operator">=</span><span class="token number">0</span><span class="token punctuation">,</span>tot_send<span class="token operator">=</span><span class="token number">0</span><span class="token punctuation">;</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="101"></td><td><pre> <span class="token keyword">char</span> buf<span class="token punctuation">[</span>BUF_SIZE<span class="token punctuation">]</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="102"></td><td><pre> <span class="token keyword">char</span> data_pac<span class="token punctuation">[</span>BUF_SIZE<span class="token punctuation">]</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="103"></td><td><pre> timeval start<span class="token punctuation">,</span>end<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="104"></td><td><pre> <span class="token function">gettimeofday</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>start<span class="token punctuation">,</span> <span class="token constant">NULL</span><span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="105"></td><td><pre> <span class="token keyword">do</span></pre></td></tr><tr><td data-num="106"></td><td><pre> <span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="107"></td><td><pre> <span class="token function">memset</span><span class="token punctuation">(</span>data_pac<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> BUF_SIZE<span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="108"></td><td><pre> <span class="token operator">*</span><span class="token punctuation">(</span><span class="token keyword">unsigned</span> <span class="token keyword">short</span><span class="token operator">*</span><span class="token punctuation">)</span>data_pac <span class="token operator">=</span> <span class="token function">htons</span><span class="token punctuation">(</span>OPCODE_DATA<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 操作码:数据包</span></pre></td></tr><tr><td data-num="109"></td><td><pre> <span class="token operator">*</span><span class="token punctuation">(</span><span class="token keyword">unsigned</span> <span class="token keyword">short</span><span class="token operator">*</span><span class="token punctuation">)</span><span class="token punctuation">(</span>data_pac <span class="token operator">+</span> <span class="token number">2</span><span class="token punctuation">)</span> <span class="token operator">=</span> <span class="token function">htons</span><span class="token punctuation">(</span>block<span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="110"></td><td><pre></pre></td></tr><tr><td data-num="111"></td><td><pre> bytes_read<span class="token operator">=</span><span class="token function">fread</span><span class="token punctuation">(</span>data_pac<span class="token operator">+</span><span class="token number">4</span><span class="token punctuation">,</span><span class="token number">1</span><span class="token punctuation">,</span>DATA_SIZE<span class="token punctuation">,</span>file<span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="112"></td><td><pre> <span class="token keyword">int</span> tot_retry<span class="token operator">=</span><span class="token number">0</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="113"></td><td><pre> <span class="token keyword">bool</span> ack<span class="token operator">=</span><span class="token boolean">false</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="114"></td><td><pre> <span class="token keyword">if</span><span class="token punctuation">(</span>bytes_read<span class="token operator">&lt;</span><span class="token number">0</span><span class="token punctuation">)</span></pre></td></tr><tr><td data-num="115"></td><td><pre> <span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="116"></td><td><pre> cerr<span class="token operator">&lt;&lt;</span><span class="token string">"ERROR: Reading file"</span><span class="token operator">&lt;&lt;</span>endl<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="117"></td><td><pre> ERRORthings packet<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="118"></td><td><pre> packet<span class="token punctuation">.</span><span class="token function">init</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token string">"Read error"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="119"></td><td><pre> packet<span class="token punctuation">.</span><span class="token function">work</span><span class="token punctuation">(</span>socketfd<span class="token punctuation">,</span>client_addr<span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="120"></td><td><pre> <span class="token keyword">break</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="121"></td><td><pre> <span class="token punctuation">&#125;</span></pre></td></tr><tr><td data-num="122"></td><td><pre> <span class="token keyword">int</span> recv_len<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="123"></td><td><pre> <span class="token keyword">while</span><span class="token punctuation">(</span><span class="token operator">!</span>ack<span class="token operator">&amp;&amp;</span>tot_retry<span class="token operator">&lt;</span>MAX_RETRIES<span class="token punctuation">)</span></pre></td></tr><tr><td data-num="124"></td><td><pre> <span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="125"></td><td><pre> <span class="token function">sendto</span><span class="token punctuation">(</span>socketfd<span class="token punctuation">,</span> data_pac<span class="token punctuation">,</span> bytes_read <span class="token operator">+</span> <span class="token number">4</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token punctuation">(</span>sockaddr<span class="token operator">*</span><span class="token punctuation">)</span><span class="token operator">&amp;</span>client_addr<span class="token punctuation">,</span> client_addr_len<span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="126"></td><td><pre> <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"sending NO.%hu packet"</span><span class="token punctuation">,</span> block<span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="127"></td><td><pre> <span class="token comment">// 超时重传</span></pre></td></tr><tr><td data-num="128"></td><td><pre> <span class="token keyword">struct</span> <span class="token class-name">timeval</span> tv<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="129"></td><td><pre> tv<span class="token punctuation">.</span>tv_sec<span class="token operator">=</span>TIMEOUT<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="130"></td><td><pre> tv<span class="token punctuation">.</span>tv_usec<span class="token operator">=</span><span class="token number">0</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="131"></td><td><pre> fd_set read_fds<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="132"></td><td><pre> <span class="token function">FD_ZERO</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>read_fds<span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="133"></td><td><pre> <span class="token function">FD_SET</span><span class="token punctuation">(</span>socketfd<span class="token punctuation">,</span> <span class="token operator">&amp;</span>read_fds<span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="134"></td><td><pre> <span class="token comment">// 传入 ACK 或超时</span></pre></td></tr><tr><td data-num="135"></td><td><pre> <span class="token keyword">int</span> select_result <span class="token operator">=</span> <span class="token function">select</span><span class="token punctuation">(</span>socketfd <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token operator">&amp;</span>read_fds<span class="token punctuation">,</span> <span class="token constant">NULL</span><span class="token punctuation">,</span> <span class="token constant">NULL</span><span class="token punctuation">,</span> <span class="token operator">&amp;</span>tv<span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="136"></td><td><pre> <span class="token keyword">if</span><span class="token punctuation">(</span>select_result<span class="token operator">></span><span class="token number">0</span><span class="token punctuation">)</span></pre></td></tr><tr><td data-num="137"></td><td><pre> <span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="138"></td><td><pre> recv_len<span class="token operator">=</span><span class="token function">recvfrom</span><span class="token punctuation">(</span>socketfd<span class="token punctuation">,</span>buf<span class="token punctuation">,</span>BUF_SIZE<span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token punctuation">(</span>sockaddr<span class="token operator">*</span><span class="token punctuation">)</span><span class="token operator">&amp;</span>client_addr<span class="token punctuation">,</span><span class="token operator">&amp;</span>client_addr_len<span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="139"></td><td><pre> <span class="token keyword">if</span><span class="token punctuation">(</span>recv_len<span class="token operator">>=</span><span class="token number">4</span><span class="token operator">&amp;&amp;</span><span class="token function">ntohs</span><span class="token punctuation">(</span><span class="token operator">*</span><span class="token punctuation">(</span><span class="token keyword">unsigned</span> <span class="token keyword">short</span><span class="token operator">*</span><span class="token punctuation">)</span>buf<span class="token punctuation">)</span><span class="token operator">==</span>OPCODE_ACK<span class="token operator">&amp;&amp;</span><span class="token function">ntohs</span><span class="token punctuation">(</span><span class="token operator">*</span><span class="token punctuation">(</span><span class="token keyword">unsigned</span> <span class="token keyword">short</span><span class="token operator">*</span><span class="token punctuation">)</span><span class="token punctuation">(</span>buf <span class="token operator">+</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token operator">==</span>block<span class="token punctuation">)</span></pre></td></tr><tr><td data-num="140"></td><td><pre> <span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="141"></td><td><pre> <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">",recived NO.%hupacket\n"</span><span class="token punctuation">,</span> block<span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="142"></td><td><pre> ack<span class="token operator">=</span><span class="token boolean">true</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="143"></td><td><pre> <span class="token punctuation">&#125;</span></pre></td></tr><tr><td data-num="144"></td><td><pre> <span class="token keyword">else</span></pre></td></tr><tr><td data-num="145"></td><td><pre> <span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="146"></td><td><pre> <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">",ACK invalid,send NO.%hupacket again\n"</span><span class="token punctuation">,</span> block<span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="147"></td><td><pre> tot_retry<span class="token operator">++</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="148"></td><td><pre> <span class="token punctuation">&#125;</span></pre></td></tr><tr><td data-num="149"></td><td><pre> <span class="token punctuation">&#125;</span></pre></td></tr><tr><td data-num="150"></td><td><pre> <span class="token keyword">else</span> <span class="token keyword">if</span><span class="token punctuation">(</span>select_result<span class="token operator">==</span><span class="token number">0</span><span class="token punctuation">)</span></pre></td></tr><tr><td data-num="151"></td><td><pre> <span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="152"></td><td><pre> <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"Timeout,retry sending NO.%hu packet\n"</span><span class="token punctuation">,</span>block<span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="153"></td><td><pre> tot_retry<span class="token operator">++</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="154"></td><td><pre> <span class="token punctuation">&#125;</span></pre></td></tr><tr><td data-num="155"></td><td><pre> <span class="token keyword">else</span></pre></td></tr><tr><td data-num="156"></td><td><pre> <span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="157"></td><td><pre> <span class="token function">perror</span><span class="token punctuation">(</span><span class="token string">"select() error"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="158"></td><td><pre> <span class="token function">fclose</span><span class="token punctuation">(</span>file<span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="159"></td><td><pre> <span class="token keyword">return</span> <span class="token punctuation">;</span></pre></td></tr><tr><td data-num="160"></td><td><pre> <span class="token punctuation">&#125;</span></pre></td></tr><tr><td data-num="161"></td><td><pre> <span class="token punctuation">&#125;</span></pre></td></tr><tr><td data-num="162"></td><td><pre> tot_send<span class="token operator">+=</span>bytes_read<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="163"></td><td><pre> block<span class="token operator">++</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="164"></td><td><pre> <span class="token punctuation">&#125;</span><span class="token keyword">while</span><span class="token punctuation">(</span>bytes_read<span class="token operator">==</span>DATA_SIZE<span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="165"></td><td><pre> <span class="token function">fclose</span><span class="token punctuation">(</span>file<span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="166"></td><td><pre> <span class="token function">gettimeofday</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>end<span class="token punctuation">,</span> <span class="token constant">NULL</span><span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="167"></td><td><pre> <span class="token keyword">double</span> time_taken<span class="token operator">=</span><span class="token punctuation">(</span>end<span class="token punctuation">.</span>tv_sec<span class="token operator">-</span>start<span class="token punctuation">.</span>tv_sec<span class="token punctuation">)</span><span class="token operator">+</span><span class="token punctuation">(</span>end<span class="token punctuation">.</span>tv_usec<span class="token operator">-</span>start<span class="token punctuation">.</span>tv_usec<span class="token punctuation">)</span><span class="token operator">/</span><span class="token number">1000000.0</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="168"></td><td><pre> <span class="token keyword">double</span> throughput<span class="token operator">=</span>tot_send<span class="token operator">/</span>time_taken<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="169"></td><td><pre> cerr<span class="token operator">&lt;&lt;</span><span class="token string">"Download throughput: "</span><span class="token operator">&lt;&lt;</span>throughput<span class="token operator">/</span><span class="token number">1024</span><span class="token operator">&lt;&lt;</span><span class="token string">" KB/s"</span><span class="token operator">&lt;&lt;</span>endl<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="170"></td><td><pre> <span class="token punctuation">&#125;</span></pre></td></tr><tr><td data-num="171"></td><td><pre><span class="token punctuation">&#125;</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="172"></td><td><pre></pre></td></tr><tr><td data-num="173"></td><td><pre><span class="token keyword">class</span> <span class="token class-name">WRQ</span></pre></td></tr><tr><td data-num="174"></td><td><pre><span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="175"></td><td><pre> <span class="token keyword">public</span><span class="token operator">:</span></pre></td></tr><tr><td data-num="176"></td><td><pre> <span class="token keyword">void</span> <span class="token function">work</span><span class="token punctuation">(</span><span class="token keyword">const</span> <span class="token keyword">char</span> <span class="token operator">*</span>filename<span class="token punctuation">,</span> <span class="token keyword">const</span> <span class="token keyword">char</span> <span class="token operator">*</span>mode<span class="token punctuation">,</span> <span class="token keyword">int</span> socketfd<span class="token punctuation">,</span> <span class="token keyword">struct</span> <span class="token class-name">sockaddr_in</span> <span class="token operator">&amp;</span>client_addr<span class="token punctuation">)</span></pre></td></tr><tr><td data-num="177"></td><td><pre> <span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="178"></td><td><pre> FILE <span class="token operator">*</span>file<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="179"></td><td><pre> <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token function">strcmp</span><span class="token punctuation">(</span>mode<span class="token punctuation">,</span><span class="token string">"netascii"</span><span class="token punctuation">)</span><span class="token operator">==</span><span class="token number">0</span><span class="token punctuation">)</span></pre></td></tr><tr><td data-num="180"></td><td><pre> file<span class="token operator">=</span><span class="token function">fopen</span><span class="token punctuation">(</span>filename<span class="token punctuation">,</span><span class="token string">"w"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="181"></td><td><pre> <span class="token keyword">else</span> file<span class="token operator">=</span><span class="token function">fopen</span><span class="token punctuation">(</span>filename<span class="token punctuation">,</span><span class="token string">"wb"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="182"></td><td><pre> <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token operator">!</span>file<span class="token punctuation">)</span></pre></td></tr><tr><td data-num="183"></td><td><pre> <span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="184"></td><td><pre> cerr<span class="token operator">&lt;&lt;</span><span class="token string">"ERROR: Cannot open file for writing: "</span><span class="token operator">&lt;&lt;</span>filename<span class="token operator">&lt;&lt;</span>endl<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="185"></td><td><pre> ERRORthings error_packet<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="186"></td><td><pre> error_packet<span class="token punctuation">.</span><span class="token function">init</span><span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">,</span>tftp_error_msg<span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="187"></td><td><pre> error_packet<span class="token punctuation">.</span><span class="token function">work</span><span class="token punctuation">(</span>socketfd<span class="token punctuation">,</span> client_addr<span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="188"></td><td><pre> <span class="token keyword">return</span> <span class="token punctuation">;</span></pre></td></tr><tr><td data-num="189"></td><td><pre> <span class="token punctuation">&#125;</span></pre></td></tr><tr><td data-num="190"></td><td><pre> <span class="token keyword">int</span> tot_recv<span class="token operator">=</span><span class="token number">0</span><span class="token punctuation">,</span>recv_len<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="191"></td><td><pre> <span class="token keyword">unsigned</span> <span class="token keyword">short</span> block<span class="token operator">=</span><span class="token number">0</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="192"></td><td><pre> <span class="token keyword">struct</span> <span class="token class-name">timeval</span> start<span class="token punctuation">,</span>end<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="193"></td><td><pre> <span class="token keyword">char</span> buf<span class="token punctuation">[</span>BUF_SIZE<span class="token punctuation">]</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="194"></td><td><pre> <span class="token function">gettimeofday</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>start<span class="token punctuation">,</span> <span class="token constant">NULL</span><span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="195"></td><td><pre> <span class="token keyword">unsigned</span> <span class="token keyword">short</span> expected_block <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span> <span class="token comment">// TFTP WRQ 开始时,第一个数据包的 block 是 1</span></pre></td></tr><tr><td data-num="196"></td><td><pre> <span class="token keyword">do</span> <span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="197"></td><td><pre> <span class="token function">memset</span><span class="token punctuation">(</span>buf<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> BUF_SIZE<span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="198"></td><td><pre></pre></td></tr><tr><td data-num="199"></td><td><pre> <span class="token comment">// 发送 ACK 包</span></pre></td></tr><tr><td data-num="200"></td><td><pre> <span class="token operator">*</span><span class="token punctuation">(</span><span class="token keyword">unsigned</span> <span class="token keyword">short</span> <span class="token operator">*</span><span class="token punctuation">)</span>buf <span class="token operator">=</span> <span class="token function">htons</span><span class="token punctuation">(</span>OPCODE_ACK<span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="201"></td><td><pre> <span class="token operator">*</span><span class="token punctuation">(</span><span class="token keyword">unsigned</span> <span class="token keyword">short</span> <span class="token operator">*</span><span class="token punctuation">)</span><span class="token punctuation">(</span>buf <span class="token operator">+</span> <span class="token number">2</span><span class="token punctuation">)</span> <span class="token operator">=</span> <span class="token function">htons</span><span class="token punctuation">(</span>expected_block <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// ACK 上一块的 block</span></pre></td></tr><tr><td data-num="202"></td><td><pre> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">sendto</span><span class="token punctuation">(</span>socketfd<span class="token punctuation">,</span> buf<span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token punctuation">(</span>sockaddr <span class="token operator">*</span><span class="token punctuation">)</span><span class="token operator">&amp;</span>client_addr<span class="token punctuation">,</span> client_addr_len<span class="token punctuation">)</span> <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="203"></td><td><pre> <span class="token function">perror</span><span class="token punctuation">(</span><span class="token string">"sendto failed"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="204"></td><td><pre> <span class="token function">fclose</span><span class="token punctuation">(</span>file<span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="205"></td><td><pre> <span class="token keyword">return</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="206"></td><td><pre> <span class="token punctuation">&#125;</span></pre></td></tr><tr><td data-num="207"></td><td><pre></pre></td></tr><tr><td data-num="208"></td><td><pre> <span class="token comment">// 接收数据包</span></pre></td></tr><tr><td data-num="209"></td><td><pre> recv_len <span class="token operator">=</span> <span class="token function">recvfrom</span><span class="token punctuation">(</span>socketfd<span class="token punctuation">,</span> buf<span class="token punctuation">,</span> BUF_SIZE<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token punctuation">(</span>sockaddr <span class="token operator">*</span><span class="token punctuation">)</span><span class="token operator">&amp;</span>client_addr<span class="token punctuation">,</span> <span class="token operator">&amp;</span>client_addr_len<span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="210"></td><td><pre> <span class="token keyword">if</span> <span class="token punctuation">(</span>recv_len <span class="token operator">&lt;</span> <span class="token number">4</span> <span class="token operator">||</span> <span class="token function">ntohs</span><span class="token punctuation">(</span><span class="token operator">*</span><span class="token punctuation">(</span><span class="token keyword">unsigned</span> <span class="token keyword">short</span> <span class="token operator">*</span><span class="token punctuation">)</span>buf<span class="token punctuation">)</span> <span class="token operator">!=</span> OPCODE_DATA<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="211"></td><td><pre> <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"The packet received is not a valid data packet\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="212"></td><td><pre> ERRORthings error_packet<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="213"></td><td><pre> error_packet<span class="token punctuation">.</span><span class="token function">init</span><span class="token punctuation">(</span><span class="token number">4</span><span class="token punctuation">,</span> tftp_error_msg<span class="token punctuation">[</span><span class="token number">4</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="214"></td><td><pre> error_packet<span class="token punctuation">.</span><span class="token function">work</span><span class="token punctuation">(</span>socketfd<span class="token punctuation">,</span> client_addr<span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="215"></td><td><pre> <span class="token function">fclose</span><span class="token punctuation">(</span>file<span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="216"></td><td><pre> <span class="token keyword">return</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="217"></td><td><pre> <span class="token punctuation">&#125;</span></pre></td></tr><tr><td data-num="218"></td><td><pre></pre></td></tr><tr><td data-num="219"></td><td><pre> <span class="token comment">// 获取接收数据包的 block 编号</span></pre></td></tr><tr><td data-num="220"></td><td><pre> <span class="token keyword">unsigned</span> <span class="token keyword">short</span> received_block <span class="token operator">=</span> <span class="token function">ntohs</span><span class="token punctuation">(</span><span class="token operator">*</span><span class="token punctuation">(</span><span class="token keyword">unsigned</span> <span class="token keyword">short</span> <span class="token operator">*</span><span class="token punctuation">)</span><span class="token punctuation">(</span>buf <span class="token operator">+</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="221"></td><td><pre></pre></td></tr><tr><td data-num="222"></td><td><pre> <span class="token keyword">if</span> <span class="token punctuation">(</span>received_block <span class="token operator">==</span> expected_block<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="223"></td><td><pre> <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"Received block NO.%hu\n"</span><span class="token punctuation">,</span> received_block<span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="224"></td><td><pre> tot_recv <span class="token operator">+=</span> recv_len <span class="token operator">-</span> <span class="token number">4</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="225"></td><td><pre> <span class="token function">fwrite</span><span class="token punctuation">(</span>buf <span class="token operator">+</span> <span class="token number">4</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">,</span> recv_len <span class="token operator">-</span> <span class="token number">4</span><span class="token punctuation">,</span> file<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 写入文件</span></pre></td></tr><tr><td data-num="226"></td><td><pre> expected_block<span class="token operator">++</span><span class="token punctuation">;</span> <span class="token comment">// 仅在收到正确的数据包时递增</span></pre></td></tr><tr><td data-num="227"></td><td><pre> <span class="token punctuation">&#125;</span> <span class="token keyword">else</span> <span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="228"></td><td><pre> <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"Duplicate or out-of-order packet, expected block: %hu, received block: %hu\n"</span><span class="token punctuation">,</span> expected_block<span class="token punctuation">,</span> received_block<span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="229"></td><td><pre> <span class="token punctuation">&#125;</span></pre></td></tr><tr><td data-num="230"></td><td><pre> <span class="token punctuation">&#125;</span> <span class="token keyword">while</span> <span class="token punctuation">(</span>recv_len <span class="token operator">==</span> DATA_SIZE <span class="token operator">+</span> <span class="token number">4</span><span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="231"></td><td><pre> <span class="token function">memset</span><span class="token punctuation">(</span>buf<span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span>BUF_SIZE<span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="232"></td><td><pre> <span class="token operator">*</span><span class="token punctuation">(</span><span class="token keyword">unsigned</span> <span class="token keyword">short</span><span class="token operator">*</span><span class="token punctuation">)</span>buf <span class="token operator">=</span> <span class="token function">htons</span><span class="token punctuation">(</span>OPCODE_ACK<span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="233"></td><td><pre> <span class="token operator">*</span><span class="token punctuation">(</span><span class="token keyword">unsigned</span> <span class="token keyword">short</span><span class="token operator">*</span><span class="token punctuation">)</span><span class="token punctuation">(</span>buf <span class="token operator">+</span> <span class="token number">2</span><span class="token punctuation">)</span> <span class="token operator">=</span> <span class="token function">htons</span><span class="token punctuation">(</span>expected_block<span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="234"></td><td><pre> <span class="token function">sendto</span><span class="token punctuation">(</span>socketfd<span class="token punctuation">,</span>buf<span class="token punctuation">,</span><span class="token number">4</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token punctuation">(</span>sockaddr<span class="token operator">*</span><span class="token punctuation">)</span><span class="token operator">&amp;</span>client_addr<span class="token punctuation">,</span>client_addr_len<span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="235"></td><td><pre> <span class="token function">fclose</span><span class="token punctuation">(</span>file<span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="236"></td><td><pre> <span class="token function">gettimeofday</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>end<span class="token punctuation">,</span> <span class="token constant">NULL</span><span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="237"></td><td><pre> <span class="token keyword">double</span> time_taken<span class="token operator">=</span><span class="token punctuation">(</span>end<span class="token punctuation">.</span>tv_sec<span class="token operator">-</span>start<span class="token punctuation">.</span>tv_sec<span class="token punctuation">)</span><span class="token operator">+</span><span class="token punctuation">(</span>end<span class="token punctuation">.</span>tv_usec<span class="token operator">-</span>start<span class="token punctuation">.</span>tv_usec<span class="token punctuation">)</span><span class="token operator">/</span><span class="token number">1000000.0</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="238"></td><td><pre> <span class="token keyword">double</span> throughput<span class="token operator">=</span>tot_recv<span class="token operator">/</span>time_taken<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="239"></td><td><pre> cerr<span class="token operator">&lt;&lt;</span><span class="token string">"Download throughput: "</span><span class="token operator">&lt;&lt;</span>throughput<span class="token operator">/</span><span class="token number">1024</span><span class="token operator">&lt;&lt;</span><span class="token string">" KB/s"</span><span class="token operator">&lt;&lt;</span>endl<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="240"></td><td><pre> <span class="token function">fclose</span><span class="token punctuation">(</span>file<span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="241"></td><td><pre> <span class="token punctuation">&#125;</span></pre></td></tr><tr><td data-num="242"></td><td><pre><span class="token punctuation">&#125;</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="243"></td><td><pre></pre></td></tr><tr><td data-num="244"></td><td><pre><span class="token keyword">class</span> <span class="token class-name">TFTP_Solve</span></pre></td></tr><tr><td data-num="245"></td><td><pre><span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="246"></td><td><pre> <span class="token keyword">private</span><span class="token operator">:</span></pre></td></tr><tr><td data-num="247"></td><td><pre> <span class="token keyword">int</span> socketfd<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="248"></td><td><pre> sockaddr_in client_addr<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="249"></td><td><pre> <span class="token keyword">char</span> buf<span class="token punctuation">[</span>BUF_SIZE<span class="token punctuation">]</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="250"></td><td><pre></pre></td></tr><tr><td data-num="251"></td><td><pre> <span class="token keyword">public</span><span class="token operator">:</span></pre></td></tr><tr><td data-num="252"></td><td><pre> <span class="token function">TFTP_Solve</span><span class="token punctuation">(</span><span class="token keyword">int</span> _socketfd<span class="token punctuation">,</span>sockaddr_in <span class="token operator">&amp;</span>_client_addr<span class="token punctuation">)</span><span class="token operator">:</span> <span class="token function">socketfd</span><span class="token punctuation">(</span>_socketfd<span class="token punctuation">)</span><span class="token punctuation">,</span><span class="token function">client_addr</span><span class="token punctuation">(</span>_client_addr<span class="token punctuation">)</span><span class="token punctuation">&#123;</span><span class="token punctuation">&#125;</span></pre></td></tr><tr><td data-num="253"></td><td><pre> <span class="token keyword">void</span> <span class="token function">Work_for_RRQ</span><span class="token punctuation">(</span><span class="token keyword">const</span> <span class="token keyword">char</span> <span class="token operator">*</span>filname<span class="token punctuation">,</span><span class="token keyword">const</span> <span class="token keyword">char</span> <span class="token operator">*</span>mode<span class="token punctuation">)</span></pre></td></tr><tr><td data-num="254"></td><td><pre> <span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="255"></td><td><pre> RRQ RRQproject<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="256"></td><td><pre> RRQproject<span class="token punctuation">.</span><span class="token function">work</span><span class="token punctuation">(</span>filname<span class="token punctuation">,</span>mode<span class="token punctuation">,</span>socketfd<span class="token punctuation">,</span>client_addr<span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="257"></td><td><pre> <span class="token punctuation">&#125;</span></pre></td></tr><tr><td data-num="258"></td><td><pre> <span class="token keyword">void</span> <span class="token function">Work_for_WRQ</span><span class="token punctuation">(</span><span class="token keyword">const</span> <span class="token keyword">char</span> <span class="token operator">*</span>filname<span class="token punctuation">,</span><span class="token keyword">const</span> <span class="token keyword">char</span> <span class="token operator">*</span>mode<span class="token punctuation">)</span></pre></td></tr><tr><td data-num="259"></td><td><pre> <span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="260"></td><td><pre> WRQ WRQproject<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="261"></td><td><pre> WRQproject<span class="token punctuation">.</span><span class="token function">work</span><span class="token punctuation">(</span>filname<span class="token punctuation">,</span>mode<span class="token punctuation">,</span>socketfd<span class="token punctuation">,</span>client_addr<span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="262"></td><td><pre> <span class="token punctuation">&#125;</span></pre></td></tr><tr><td data-num="263"></td><td><pre> <span class="token keyword">void</span> <span class="token function">work</span><span class="token punctuation">(</span><span class="token punctuation">)</span></pre></td></tr><tr><td data-num="264"></td><td><pre> <span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="265"></td><td><pre> <span class="token keyword">int</span> rev_len<span class="token operator">=</span><span class="token function">recvfrom</span><span class="token punctuation">(</span>socketfd<span class="token punctuation">,</span>buf<span class="token punctuation">,</span>BUF_SIZE<span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token punctuation">(</span>sockaddr <span class="token operator">*</span><span class="token punctuation">)</span><span class="token operator">&amp;</span>client_addr<span class="token punctuation">,</span><span class="token operator">&amp;</span>client_addr_len<span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="266"></td><td><pre> <span class="token keyword">if</span><span class="token punctuation">(</span>rev_len<span class="token operator">&lt;</span><span class="token number">4</span><span class="token punctuation">)</span></pre></td></tr><tr><td data-num="267"></td><td><pre> <span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="268"></td><td><pre> cerr<span class="token operator">&lt;&lt;</span><span class="token string">"ERROR: Can't receive request"</span><span class="token operator">&lt;&lt;</span>endl<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="269"></td><td><pre> ERRORthings packet<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="270"></td><td><pre> packet<span class="token punctuation">.</span><span class="token function">init</span><span class="token punctuation">(</span><span class="token number">4</span><span class="token punctuation">,</span>tftp_error_msg<span class="token punctuation">[</span><span class="token number">4</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="271"></td><td><pre> packet<span class="token punctuation">.</span><span class="token function">work</span><span class="token punctuation">(</span>socketfd<span class="token punctuation">,</span> client_addr<span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="272"></td><td><pre> <span class="token keyword">return</span> <span class="token punctuation">;</span></pre></td></tr><tr><td data-num="273"></td><td><pre> <span class="token punctuation">&#125;</span></pre></td></tr><tr><td data-num="274"></td><td><pre> <span class="token keyword">short</span> opcode<span class="token operator">=</span><span class="token function">ntohs</span><span class="token punctuation">(</span><span class="token operator">*</span><span class="token punctuation">(</span><span class="token keyword">unsigned</span> <span class="token keyword">short</span> <span class="token operator">*</span><span class="token punctuation">)</span>buf<span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="275"></td><td><pre> <span class="token keyword">char</span> <span class="token operator">*</span>filename<span class="token operator">=</span>buf<span class="token operator">+</span><span class="token number">2</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="276"></td><td><pre> <span class="token keyword">char</span> <span class="token operator">*</span>mode<span class="token operator">=</span>filename<span class="token operator">+</span><span class="token function">strlen</span><span class="token punctuation">(</span>filename<span class="token punctuation">)</span><span class="token operator">+</span><span class="token number">1</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="277"></td><td><pre></pre></td></tr><tr><td data-num="278"></td><td><pre> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">strcmp</span><span class="token punctuation">(</span>mode<span class="token punctuation">,</span> <span class="token string">"netascii"</span><span class="token punctuation">)</span> <span class="token operator">!=</span> <span class="token number">0</span> <span class="token operator">&amp;&amp;</span> <span class="token function">strcmp</span><span class="token punctuation">(</span>mode<span class="token punctuation">,</span> <span class="token string">"octet"</span><span class="token punctuation">)</span> <span class="token operator">!=</span> <span class="token number">0</span><span class="token punctuation">)</span></pre></td></tr><tr><td data-num="279"></td><td><pre> <span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="280"></td><td><pre> ERRORthings packet<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="281"></td><td><pre> packet<span class="token punctuation">.</span><span class="token function">init</span><span class="token punctuation">(</span><span class="token number">4</span><span class="token punctuation">,</span><span class="token string">"Unsupported transfer mode."</span><span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="282"></td><td><pre> packet<span class="token punctuation">.</span><span class="token function">work</span><span class="token punctuation">(</span>socketfd<span class="token punctuation">,</span> client_addr<span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="283"></td><td><pre> <span class="token keyword">return</span> <span class="token punctuation">;</span></pre></td></tr><tr><td data-num="284"></td><td><pre> <span class="token punctuation">&#125;</span></pre></td></tr><tr><td data-num="285"></td><td><pre></pre></td></tr><tr><td data-num="286"></td><td><pre> <span class="token keyword">if</span><span class="token punctuation">(</span>opcode<span class="token operator">==</span>OPCODE_RRQ<span class="token punctuation">)</span> <span class="token function">Work_for_RRQ</span><span class="token punctuation">(</span>filename<span class="token punctuation">,</span>mode<span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="287"></td><td><pre> <span class="token keyword">else</span> <span class="token keyword">if</span><span class="token punctuation">(</span>opcode<span class="token operator">==</span>OPCODE_WRQ<span class="token punctuation">)</span> <span class="token function">Work_for_WRQ</span><span class="token punctuation">(</span>filename<span class="token punctuation">,</span>mode<span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="288"></td><td><pre> <span class="token keyword">else</span> <span class="token keyword">if</span><span class="token punctuation">(</span>opcode<span class="token operator">==</span>OPCODE_ERROR<span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="289"></td><td><pre> <span class="token keyword">else</span></pre></td></tr><tr><td data-num="290"></td><td><pre> <span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="291"></td><td><pre> cerr<span class="token operator">&lt;&lt;</span><span class="token string">"ERROR: Unknown request"</span><span class="token operator">&lt;&lt;</span>endl<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="292"></td><td><pre> ERRORthings packet<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="293"></td><td><pre> packet<span class="token punctuation">.</span><span class="token function">init</span><span class="token punctuation">(</span><span class="token number">4</span><span class="token punctuation">,</span>tftp_error_msg<span class="token punctuation">[</span><span class="token number">4</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="294"></td><td><pre> packet<span class="token punctuation">.</span><span class="token function">work</span><span class="token punctuation">(</span>socketfd<span class="token punctuation">,</span>client_addr<span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="295"></td><td><pre> <span class="token punctuation">&#125;</span></pre></td></tr><tr><td data-num="296"></td><td><pre> <span class="token punctuation">&#125;</span></pre></td></tr><tr><td data-num="297"></td><td><pre><span class="token punctuation">&#125;</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="298"></td><td><pre></pre></td></tr><tr><td data-num="299"></td><td><pre><span class="token keyword">class</span> <span class="token class-name">Server</span></pre></td></tr><tr><td data-num="300"></td><td><pre><span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="301"></td><td><pre> <span class="token keyword">private</span><span class="token operator">:</span></pre></td></tr><tr><td data-num="302"></td><td><pre> <span class="token keyword">int</span> socketfd<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="303"></td><td><pre> </pre></td></tr><tr><td data-num="304"></td><td><pre> <span class="token keyword">public</span><span class="token operator">:</span></pre></td></tr><tr><td data-num="305"></td><td><pre> <span class="token function">Server</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">:</span> <span class="token function">socketfd</span><span class="token punctuation">(</span><span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span><span class="token punctuation">&#125;</span></pre></td></tr><tr><td data-num="306"></td><td><pre> sockaddr_in <span class="token function">getAddr</span><span class="token punctuation">(</span><span class="token keyword">const</span> <span class="token keyword">char</span> <span class="token operator">*</span>ip<span class="token punctuation">,</span><span class="token keyword">int</span> port<span class="token punctuation">)</span></pre></td></tr><tr><td data-num="307"></td><td><pre> <span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="308"></td><td><pre> sockaddr_in addr<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="309"></td><td><pre> addr<span class="token punctuation">.</span>sin_family <span class="token operator">=</span> AF_INET<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="310"></td><td><pre> addr<span class="token punctuation">.</span>sin_port <span class="token operator">=</span> <span class="token function">htons</span><span class="token punctuation">(</span>port<span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="311"></td><td><pre> addr<span class="token punctuation">.</span>sin_addr<span class="token punctuation">.</span>S_un<span class="token punctuation">.</span>S_addr <span class="token operator">=</span> INADDR_ANY<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="312"></td><td><pre> <span class="token keyword">return</span> addr<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="313"></td><td><pre> <span class="token punctuation">&#125;</span></pre></td></tr><tr><td data-num="314"></td><td><pre> <span class="token keyword">void</span> <span class="token function">init</span><span class="token punctuation">(</span><span class="token punctuation">)</span></pre></td></tr><tr><td data-num="315"></td><td><pre> <span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="316"></td><td><pre> socketfd <span class="token operator">=</span> <span class="token function">socket</span><span class="token punctuation">(</span>AF_INET<span class="token punctuation">,</span> SOCK_DGRAM<span class="token punctuation">,</span> IPPROTO_UDP<span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="317"></td><td><pre> <span class="token keyword">if</span><span class="token punctuation">(</span>socketfd<span class="token operator">&lt;</span><span class="token number">0</span><span class="token punctuation">)</span></pre></td></tr><tr><td data-num="318"></td><td><pre> <span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="319"></td><td><pre> cerr<span class="token operator">&lt;&lt;</span><span class="token string">"Error creating socket..."</span><span class="token operator">&lt;&lt;</span>endl<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="320"></td><td><pre> <span class="token function">exit</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="321"></td><td><pre> <span class="token punctuation">&#125;</span></pre></td></tr><tr><td data-num="322"></td><td><pre> sockaddr_in server_addr <span class="token operator">=</span> <span class="token function">getAddr</span><span class="token punctuation">(</span>IP<span class="token punctuation">,</span> PORT<span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="323"></td><td><pre> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">bind</span><span class="token punctuation">(</span>socketfd<span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token keyword">struct</span> <span class="token class-name">sockaddr</span> <span class="token operator">*</span><span class="token punctuation">)</span> <span class="token operator">&amp;</span>server_addr<span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>server_addr<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="324"></td><td><pre> cerr<span class="token operator">&lt;&lt;</span><span class="token string">"Bind local port failed!"</span><span class="token operator">&lt;&lt;</span>endl<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="325"></td><td><pre> <span class="token function">exit</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="326"></td><td><pre> <span class="token punctuation">&#125;</span></pre></td></tr><tr><td data-num="327"></td><td><pre> cerr<span class="token operator">&lt;&lt;</span><span class="token string">"TFTP is successfully started on port "</span><span class="token operator">&lt;&lt;</span>PORT<span class="token operator">&lt;&lt;</span><span class="token string">" at IP address "</span><span class="token operator">&lt;&lt;</span>IP<span class="token operator">&lt;&lt;</span>endl<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="328"></td><td><pre> <span class="token punctuation">&#125;</span></pre></td></tr><tr><td data-num="329"></td><td><pre> <span class="token keyword">void</span> <span class="token function">work</span><span class="token punctuation">(</span><span class="token punctuation">)</span></pre></td></tr><tr><td data-num="330"></td><td><pre> <span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="331"></td><td><pre> <span class="token keyword">while</span><span class="token punctuation">(</span><span class="token boolean">true</span><span class="token punctuation">)</span></pre></td></tr><tr><td data-num="332"></td><td><pre> <span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="333"></td><td><pre> sockaddr_in client_addr<span class="token punctuation">;</span> client_addr_len<span class="token operator">=</span><span class="token keyword">sizeof</span><span class="token punctuation">(</span>client_addr<span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="334"></td><td><pre> TFTP_Solve <span class="token function">project</span><span class="token punctuation">(</span>socketfd<span class="token punctuation">,</span>client_addr<span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="335"></td><td><pre> project<span class="token punctuation">.</span><span class="token function">work</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="336"></td><td><pre> <span class="token punctuation">&#125;</span></pre></td></tr><tr><td data-num="337"></td><td><pre> <span class="token punctuation">&#125;</span></pre></td></tr><tr><td data-num="338"></td><td><pre> <span class="token operator">~</span><span class="token function">Server</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span><span class="token keyword">if</span><span class="token punctuation">(</span>socketfd<span class="token operator">!=</span><span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">)</span> <span class="token function">closesocket</span><span class="token punctuation">(</span>socketfd<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span></pre></td></tr><tr><td data-num="339"></td><td><pre><span class="token punctuation">&#125;</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="340"></td><td><pre></pre></td></tr><tr><td data-num="341"></td><td><pre></pre></td></tr><tr><td data-num="342"></td><td><pre><span class="token keyword">int</span> <span class="token function">TFTP_init</span><span class="token punctuation">(</span><span class="token punctuation">)</span></pre></td></tr><tr><td data-num="343"></td><td><pre><span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="344"></td><td><pre> WSADATA wsaData<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="345"></td><td><pre> <span class="token keyword">int</span> result <span class="token operator">=</span> <span class="token function">WSAStartup</span><span class="token punctuation">(</span><span class="token function">MAKEWORD</span><span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token operator">&amp;</span>wsaData<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 初始化 Winsock</span></pre></td></tr><tr><td data-num="346"></td><td><pre> <span class="token keyword">if</span> <span class="token punctuation">(</span>result <span class="token operator">!=</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="347"></td><td><pre> cerr<span class="token operator">&lt;&lt;</span><span class="token string">"WSAStartup failed: "</span><span class="token operator">&lt;&lt;</span>result<span class="token operator">&lt;&lt;</span>endl<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="348"></td><td><pre> <span class="token keyword">return</span> <span class="token number">1</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="349"></td><td><pre> <span class="token punctuation">&#125;</span></pre></td></tr><tr><td data-num="350"></td><td><pre> <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"Winsock initialized.\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="351"></td><td><pre> <span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="352"></td><td><pre><span class="token punctuation">&#125;</span></pre></td></tr><tr><td data-num="353"></td><td><pre></pre></td></tr><tr><td data-num="354"></td><td><pre><span class="token keyword">int</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span></pre></td></tr><tr><td data-num="355"></td><td><pre><span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="356"></td><td><pre> <span class="token function">TFTP_init</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="357"></td><td><pre> Server S<span class="token punctuation">;</span> S<span class="token punctuation">.</span><span class="token function">init</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> S<span class="token punctuation">.</span><span class="token function">work</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="358"></td><td><pre> <span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="359"></td><td><pre><span class="token punctuation">&#125;</span></pre></td></tr></table></figure></content>
<updated>2024-12-21T12:45:40.177Z</updated>
</entry>
<entry>
<id>http://varuxn.github.io/2024/12/21/LateX/</id>
<title>LateX</title>
<link rel="alternate" href="http://varuxn.github.io/2024/12/21/LateX/"/>
<content type="html"><p m="">组合数: <code>$\binom&#123;n&#125;&#123;m&#125;$</code> \binom{n}</p>
<p>第一类斯特林数: <code>$n \brack m$</code> <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo fence="true">[</mo><mfrac linethickness="0px"><mi>n</mi><mi>m</mi></mfrac><mo fence="true">]</mo></mrow><annotation encoding="application/x-tex">n \brack m</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.20001em;vertical-align:-0.35001em;"></span><span class="mord"><span class="mopen delimcenter" style="top:0em;"><span class="delimsizing size1">[</span></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.7453919999999999em;"><span style="top:-2.3550000000000004em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">m</span></span></span></span><span style="top:-3.144em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span></span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.345em;"><span></span></span></span></span></span><span class="mclose delimcenter" style="top:0em;"><span class="delimsizing size1">]</span></span></span></span></span></span></p>
<p>第二类斯特林数: <code>$n \brace m$</code> <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo fence="true">{</mo><mfrac linethickness="0px"><mi>n</mi><mi>m</mi></mfrac><mo fence="true">}</mo></mrow><annotation encoding="application/x-tex">n \brace m</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.20001em;vertical-align:-0.35001em;"></span><span class="mord"><span class="mopen delimcenter" style="top:0em;"><span class="delimsizing size1">{</span></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.7453919999999999em;"><span style="top:-2.3550000000000004em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">m</span></span></span></span><span style="top:-3.144em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span></span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.345em;"><span></span></span></span></span></span><span class="mclose delimcenter" style="top:0em;"><span class="delimsizing size1">}</span></span></span></span></span></span> 当然 <code>$\&#123;_m^n\&#125;$</code> <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msubsup><mo stretchy="false">{</mo><mi>m</mi><mi>n</mi></msubsup><mo stretchy="false">}</mo></mrow><annotation encoding="application/x-tex">\{_m^n\}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen"><span class="mopen">{</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.664392em;"><span style="top:-2.4530000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">m</span></span></span><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">n</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.247em;"><span></span></span></span></span></span></span><span class="mclose">}</span></span></span></span> 也可以,<s> 但是可能会丑一些</s></p>
<p m="">分数: 小的 <code>$\frac&#123;n&#125;&#123;m&#125;$</code> <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mfrac><mi>n</mi><mi>m</mi></mfrac></mrow><annotation encoding="application/x-tex">\frac{n}{m}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.040392em;vertical-align:-0.345em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.695392em;"><span style="top:-2.6550000000000002em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">m</span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span></span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.345em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span></span> 大的 <code>$\dfrac&#123;n&#125;&#123;m&#125;$</code> \dfrac{n}</p>
<p>大于等于: <code>$\ge$</code> <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo>≥</mo></mrow><annotation encoding="application/x-tex">\ge</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.7719400000000001em;vertical-align:-0.13597em;"></span><span class="mrel">≥</span></span></span></span> , 小于等于: <code>$\le$</code> <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo>≤</mo></mrow><annotation encoding="application/x-tex">\le</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.7719400000000001em;vertical-align:-0.13597em;"></span><span class="mrel">≤</span></span></span></span> , 不等于: <code>$\neq$</code> <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo mathvariant="normal">≠</mo></mrow><annotation encoding="application/x-tex">\neq</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="mrel"><span class="mrel"><span class="mord vbox"><span class="thinbox"><span class="rlap"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="inner"><span class="mrel"></span></span><span class="fix"></span></span></span></span></span><span class="mrel">=</span></span></span></span></span></p>
<p>连加: <code>$\sum$</code> <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo>∑</mo></mrow><annotation encoding="application/x-tex">\sum</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.00001em;vertical-align:-0.25001em;"></span><span class="mop op-symbol small-op" style="position:relative;top:-0.0000050000000000050004em;">∑</span></span></span></span> , 连乘: <code>$\prod$</code> <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo>∏</mo></mrow><annotation encoding="application/x-tex">\prod</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.00001em;vertical-align:-0.25001em;"></span><span class="mop op-symbol small-op" style="position:relative;top:-0.0000050000000000050004em;">∏</span></span></span></span></p>
<p>上下标搞到正上或者正下方: 在后面加上 <code>$\limits$</code></p>
<p>整行公式可以: <code>$\displaystyle$</code> 配合 <code>$$ $$</code> 使用效果更佳。</p>
<p>点乘: <code>$\cdot$</code> <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo>⋅</mo></mrow><annotation encoding="application/x-tex">\cdot</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.44445em;vertical-align:0em;"></span><span class="mord">⋅</span></span></span></span> , 叉乘: <code>$\times$</code> <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo>×</mo></mrow><annotation encoding="application/x-tex">\times</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.66666em;vertical-align:-0.08333em;"></span><span class="mord">×</span></span></span></span></p>
<p>向上取整: <code>$\lceil x \rceil$</code> <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">⌈</mo><mi>x</mi><mo stretchy="false">⌉</mo></mrow><annotation encoding="application/x-tex">\lceil x \rceil</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">⌈</span><span class="mord mathnormal">x</span><span class="mclose">⌉</span></span></span></span> , 向下取整: <code>$\lfloor x \rfloor$</code> <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">⌊</mo><mi>x</mi><mo stretchy="false">⌋</mo></mrow><annotation encoding="application/x-tex">\lfloor x \rfloor</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">⌊</span><span class="mord mathnormal">x</span><span class="mclose">⌋</span></span></span></span></p>
<p \wedge="">异或: <code>$\otimes$</code> <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo>⊗</mo></mrow><annotation encoding="application/x-tex">\otimes</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.66666em;vertical-align:-0.08333em;"></span><span class="mord">⊗</span></span></span></span> 或者 <code>$^&#123;\wedge&#125;$</code> ^</p>
<p x="">开方: <code>$\sqrt[n]&#123;x&#125;$</code> \sqrt[n]</p>
<p>属于: <code>$\in$</code> <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo>∈</mo></mrow><annotation encoding="application/x-tex">\in</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.5782em;vertical-align:-0.0391em;"></span><span class="mrel">∈</span></span></span></span> , 不属于: <code>$\notin$</code> <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo mathvariant="normal">∉</mo></mrow><annotation encoding="application/x-tex">\notin</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mrel"><span class="mord"><span class="mrel">∈</span></span><span class="mord vbox"><span class="thinbox"><span class="llap"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="inner"><span class="mord"><span class="mord">/</span><span class="mspace" style="margin-right:0.05555555555555555em;"></span></span></span><span class="fix"></span></span></span></span></span></span></span></span></p>
<p>同余: <code>$\equiv$</code> <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo>≡</mo></mrow><annotation encoding="application/x-tex">\equiv</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.46375em;vertical-align:0em;"></span><span class="mrel">≡</span></span></span></span> , 不同余: <code>$\not\equiv$</code> <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo>≢</mo></mrow><annotation encoding="application/x-tex">\not\equiv</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="mrel"><span class="mord vbox"><span class="thinbox"><span class="rlap"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="inner"><span class="mrel"></span></span><span class="fix"></span></span></span></span></span></span><span class="base"><span class="strut" style="height:0.46375em;vertical-align:0em;"></span><span class="mrel">≡</span></span></span></span></p>
<p>整除: <code>$\mid$</code> <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo>∣</mo></mrow><annotation encoding="application/x-tex">\mid</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mrel">∣</span></span></span></span> , 不整除: <code>$\nmid$</code> <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo>∤</mo></mrow><annotation encoding="application/x-tex">\nmid</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.99253em;vertical-align:-0.25142em;"></span><span class="mrel amsrm">∤</span></span></span></span></p>
<p>空格: 小 <code>$\;$</code> <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mtext> </mtext></mrow><annotation encoding="application/x-tex">\;</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0em;vertical-align:0em;"></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span></span></span>, 中 <code>$\quad$</code> <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mspace width="1em"/></mrow><annotation encoding="application/x-tex">\quad</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0em;vertical-align:0em;"></span><span class="mspace" style="margin-right:1em;"></span></span></span></span>, 大 <code>$\qquad$</code> <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mspace width="2em"/></mrow><annotation encoding="application/x-tex">\qquad</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0em;vertical-align:0em;"></span><span class="mspace" style="margin-right:2em;"></span></span></span></span></p>
<p>各种包含: <code>$\subset$</code> <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo>⊂</mo></mrow><annotation encoding="application/x-tex">\subset</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.5782em;vertical-align:-0.0391em;"></span><span class="mrel">⊂</span></span></span></span> , <code>$\supset$</code> <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo>⊃</mo></mrow><annotation encoding="application/x-tex">\supset</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.5782em;vertical-align:-0.0391em;"></span><span class="mrel">⊃</span></span></span></span> , <code>$\subseteq$</code> <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo>⊆</mo></mrow><annotation encoding="application/x-tex">\subseteq</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.7719400000000001em;vertical-align:-0.13597em;"></span><span class="mrel">⊆</span></span></span></span> , <code>$\supseteq$</code> <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo>⊇</mo></mrow><annotation encoding="application/x-tex">\supseteq</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.7719400000000001em;vertical-align:-0.13597em;"></span><span class="mrel">⊇</span></span></span></span></p>
<p>让字符变大 <code>$\big[$</code> <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo fence="false">[</mo></mrow><annotation encoding="application/x-tex">\big[</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.20001em;vertical-align:-0.35001em;"></span><span class="mord"><span class="delimsizing size1">[</span></span></span></span></span> , <code>$\Big[$</code> <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo fence="false">[</mo></mrow><annotation encoding="application/x-tex">\Big[</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.80002em;vertical-align:-0.65002em;"></span><span class="mord"><span class="delimsizing size2">[</span></span></span></span></span></p>
<p>还有一堆花里呼哨的符号: <code>$\phi$</code> <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>ϕ</mi></mrow><annotation encoding="application/x-tex">\phi</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="mord mathnormal">ϕ</span></span></span></span> <code>$\varphi$</code> <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>φ</mi></mrow><annotation encoding="application/x-tex">\varphi</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.625em;vertical-align:-0.19444em;"></span><span class="mord mathnormal">φ</span></span></span></span> <code>$\Omega$</code> <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi mathvariant="normal">Ω</mi></mrow><annotation encoding="application/x-tex">\Omega</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord">Ω</span></span></span></span> <code>$\omega$</code> <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>ω</mi></mrow><annotation encoding="application/x-tex">\omega</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">ω</span></span></span></span> <code>$\infty$</code> <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi mathvariant="normal">∞</mi></mrow><annotation encoding="application/x-tex">\infty</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord">∞</span></span></span></span></p>
<p>部分内容来自 <a href="https://www.cnblogs.com/wxyww/p/latex.html">https://www.cnblogs.com/wxyww/p/latex.html</a></p>
</content>
<updated>2024-12-21T12:42:53.204Z</updated>
</entry>
</feed>