1 00:00:00,000 --> 00:00:09,647 2 00:00:09,647 --> 00:00:11,730 演讲嘉宾:现在我们的潜水 入分配代码 3 00:00:11,730 --> 00:00:14,470 而看看上下文 在你的代码编写 4 00:00:14,470 --> 00:00:15,780 将要被运行。 5 00:00:15,780 --> 00:00:17,350 在一天结束时, 你要落实 6 00:00:17,350 --> 00:00:18,710 Web服务器的全部。 7 00:00:18,710 --> 00:00:20,460 但是,我们已经提供 你的骨架 8 00:00:20,460 --> 00:00:24,090 码具有一些功能, 特别是与网络相关的。 9 00:00:24,090 --> 00:00:25,390 让我们一起来看看。 10 00:00:25,390 --> 00:00:27,560 >> 所以在这里向顶部 该文件的是一串 11 00:00:27,560 --> 00:00:30,020 功能测试宏要求。 12 00:00:30,020 --> 00:00:33,570 现在,这是C,由此只是一个功能 根据一堆手册页 13 00:00:33,570 --> 00:00:36,410 你必须定义一些 这些常数是真实的 14 00:00:36,410 --> 00:00:39,920 或者甚至可以说具体的数字,这样 您可以访问特定的功能。 15 00:00:39,920 --> 00:00:42,470 否则,他们将未申报 您将无法访问。 16 00:00:42,470 --> 00:00:45,340 所以我用的方式做到了这一点 阅读手册页。 17 00:00:45,340 --> 00:00:48,410 现在向下跌破,在 线15至17,我们 18 00:00:48,410 --> 00:00:50,550 有一大堆宣布限制。 19 00:00:50,550 --> 00:00:53,370 >> 我们已经借了这些从 所谓的流行的Apache Web服务器。 20 00:00:53,370 --> 00:00:54,650 而这些都只是 这将会号 21 00:00:54,650 --> 00:00:56,810 封顶的总数 字节允许的 22 00:00:56,810 --> 00:01:01,930 在各种情况下的HTTP请求 该浏览器允许给我。 23 00:01:01,930 --> 00:01:04,310 接下来,我们定义字节。 24 00:01:04,310 --> 00:01:07,790 现在,一个字节仅仅是一个奇特的方式 说法一个字节或8位。 25 00:01:07,790 --> 00:01:10,720 原来在昔日一个字节 不一定八位, 26 00:01:10,720 --> 00:01:12,339 所以字节总是八位。 27 00:01:12,339 --> 00:01:14,880 所以在这种情况下,我们已经采取了 什么是常见的网络 28 00:01:14,880 --> 00:01:17,410 世界呼唤八个字节一个字节的。 29 00:01:17,410 --> 00:01:21,840 >> 在这里,我指定的字节会 是512,这样,很像在取证 30 00:01:21,840 --> 00:01:24,170 当我们读到了一堆 在时刻字节,这里也 31 00:01:24,170 --> 00:01:27,390 我们要读 束的八位位组的时间。 32 00:01:27,390 --> 00:01:28,922 接下来一大堆的头文件。 33 00:01:28,922 --> 00:01:30,255 我怎么知道要包括这些? 34 00:01:30,255 --> 00:01:32,730 好吧,我只是看过的人 对于许多功能的网页 35 00:01:32,730 --> 00:01:35,620 我们将在这个配送使用 码,并在那些包括 36 00:01:35,620 --> 00:01:37,390 我奉命。 37 00:01:37,390 --> 00:01:39,090 >> 现在我们有一个数据类型。 38 00:01:39,090 --> 00:01:41,470 我们已经宣布的字节是一个字符。 39 00:01:41,470 --> 00:01:44,040 我们将在后面看到,这是 通篇使用的代码。 40 00:01:44,040 --> 00:01:45,670 我们已经申报了 一大堆原型, 41 00:01:45,670 --> 00:01:47,961 我们将通过快速走 每个这样的功能。 42 00:01:47,961 --> 00:01:50,400 最后,也许是最 重要的是保持在 43 00:01:50,400 --> 00:01:52,520 介意此时在 的故事,是有 44 00:01:52,520 --> 00:01:54,520 是,实际上是一个整 一堆全局变量 45 00:01:54,520 --> 00:02:00,430 在该文件的顶部,根, CFD,SFD,要求,文件和身体。 46 00:02:00,430 --> 00:02:03,960 >> 现在普遍使用这么多全球 的变量,或者在所有的全局变量, 47 00:02:03,960 --> 00:02:05,280 不是背面实践。 48 00:02:05,280 --> 00:02:09,090 但事实证明,我们也使用 技术,称为信号处理后 49 00:02:09,090 --> 00:02:11,930 在代码中,这使我们能够 当用户点击一些检测 50 00:02:11,930 --> 00:02:15,080 像CTRL C和关闭 服务器正常。 51 00:02:15,080 --> 00:02:18,240 而为了做到这一点优雅 实际上释放内存, 52 00:02:18,240 --> 00:02:20,800 我们需要能够访问 这些全局变量。 53 00:02:20,800 --> 00:02:24,510 >> 现在让我们来看看主要的,这 推动这一计划的全部内容。 54 00:02:24,510 --> 00:02:27,720 首先,在顶部在这里,我们 有一个错误编号变量 55 00:02:27,720 --> 00:02:29,570 出现不 有型,但是这 56 00:02:29,570 --> 00:02:31,500 因为它实际上是 在一个名为文件中定义 57 00:02:31,500 --> 00:02:34,800 错误errno.h中哪些 包括更高了。 58 00:02:34,800 --> 00:02:38,780 如果你做男人的errno实际 看到这个东西的定义, 59 00:02:38,780 --> 00:02:41,230 你会看到,这是一个 特殊的全局变量 60 00:02:41,230 --> 00:02:43,350 由一大堆设置 功能没有写 61 00:02:43,350 --> 00:02:48,730 通过我们,但被Linux的作者 与其他系统实际设置 62 00:02:48,730 --> 00:02:52,400 一个数字,该变量的东西时, 出了问题,这样你可以在全球 63 00:02:52,400 --> 00:02:54,830 找出确实出问题。 64 00:02:54,830 --> 00:02:58,540 >> 现在,向下跌破,你会看到一个新的 技术也许使用getopt的, 65 00:02:58,540 --> 00:03:01,790 一个功能,可帮助解析命令 行参数让我们不 66 00:03:01,790 --> 00:03:05,540 费心浪费时间搞清楚 如何解析类似8080, 67 00:03:05,540 --> 00:03:08,350 或破折号p或破折号小时,得到帮助。 68 00:03:08,350 --> 00:03:10,300 getopt的本质确实是我们。 69 00:03:10,300 --> 00:03:11,750 参见手册页了解更多。 70 00:03:11,750 --> 00:03:13,960 >> 接下来,我们做了一点错误 检查,以确保 71 00:03:13,960 --> 00:03:17,420 该端口号​​是内 在指定范围内的规范。 72 00:03:17,420 --> 00:03:20,240 接下来,我们看到了一个调用函数 开始,他的定义,我们将 73 00:03:20,240 --> 00:03:24,040 看看一个时刻,正如它的名字 顾名思义,这将启动Web服务器。 74 00:03:24,040 --> 00:03:26,960 在这里,我们有一个函数调用 所谓的信号说, 75 00:03:26,960 --> 00:03:30,750 如果当你听到控制C来自 用户的键盘,继续打电话 76 00:03:30,750 --> 00:03:34,650 一个函数调用的处理程序是怎么回事 最终干净的东西和停止 77 00:03:34,650 --> 00:03:35,500 服务器。 78 00:03:35,500 --> 00:03:39,470 >> 下面是这似乎是一个 无限循环,第一线,其中 79 00:03:39,470 --> 00:03:41,660 有效的是一个电话 一个调用的函数 80 00:03:41,660 --> 00:03:45,110 复位,这是我们自己 为了实施以后 81 00:03:45,110 --> 00:03:47,470 释放一些全球国家。 82 00:03:47,470 --> 00:03:50,480 在这之后是一条线的 代码有条件 83 00:03:50,480 --> 00:03:52,576 被检查返回 连接的价值。 84 00:03:52,576 --> 00:03:55,700 现在,连看起来像一个谓语, 一些返回true或false。 85 00:03:55,700 --> 00:03:58,040 而这样做,但有 一些特殊的连接 86 00:03:58,040 --> 00:03:59,960 因为它是一个阻塞调用。 87 00:03:59,960 --> 00:04:03,180 它会坐在那里,等待 直到用户的浏览器 88 00:04:03,180 --> 00:04:05,860 尝试连接到该网络 服务器,然后才将它 89 00:04:05,860 --> 00:04:10,160 返回true或false,所以我们开始 这个if语句的内部。 90 00:04:10,160 --> 00:04:13,870 >> 一到那里,看到这个功能了 函数调用的解析,这是我们写的, 91 00:04:13,870 --> 00:04:17,230 这解析所有的八位字节,所有的 从浏览器传来的字节 92 00:04:17,230 --> 00:04:21,010 到服务器,这样我们就可以出手 你回到最终值一 93 00:04:21,010 --> 00:04:24,420 这些全局变量的那 所有门店,在短短的字节 94 00:04:24,420 --> 00:04:26,630 那头 请求,而不是体 95 00:04:26,630 --> 00:04:28,920 如果有一个真正的身体吧。 96 00:04:28,920 --> 00:04:32,980 >> 现在,向下跌破我们开始 解析这些头提取 97 00:04:32,980 --> 00:04:35,490 的信息的子集 我们所关心的。 98 00:04:35,490 --> 00:04:37,740 具体地,每 规范中,我们首先 99 00:04:37,740 --> 00:04:40,580 想请求线,这是 只是第一个行 100 00:04:40,580 --> 00:04:45,710 希望说,类似的get 削减或某些路径,然后HTTP 1.1。 101 00:04:45,710 --> 00:04:48,150 我们使用这个比喻 在大海捞针的 102 00:04:48,150 --> 00:04:50,370 寻找特定的 字符或地址。 103 00:04:50,370 --> 00:04:53,120 事实上,还有一些 在我们的分销代码函数 104 00:04:53,120 --> 00:04:56,930 你也可能会发现有用 寻找特定值时。 105 00:04:56,930 --> 00:05:00,630 >> 最终,我们复制这些字节 成可变称为线, 106 00:05:00,630 --> 00:05:03,510 该通知,我们也已经 在堆栈上分配 107 00:05:03,510 --> 00:05:05,890 通过动态调整数组的方式。 108 00:05:05,890 --> 00:05:08,350 我们正在刻意 为了避免调用malloc 109 00:05:08,350 --> 00:05:11,100 因为再次,因为 控制C是 110 00:05:11,100 --> 00:05:14,630 这一计划的潜在功能,我们 不希望有这样的代码突然 111 00:05:14,630 --> 00:05:17,479 由用户击打中断 控制C,它的结果 112 00:05:17,479 --> 00:05:20,270 是,我可能没有机会 免费的东西我malloced。 113 00:05:20,270 --> 00:05:23,660 所以我想用尽可能多 堆栈的是我可以在这里。 114 00:05:23,660 --> 00:05:26,040 >> 接下来,一大堆到DOS。 115 00:05:26,040 --> 00:05:28,930 该规范将阐述 究竟怎么在这里期待, 116 00:05:28,930 --> 00:05:31,800 但评论给你 一个什么样的暗示摆在面前。 117 00:05:31,800 --> 00:05:33,830 你首先需要 验证请求行 118 00:05:33,830 --> 00:05:37,760 并确保它看起来像 规范语法,可以这么说, 119 00:05:37,760 --> 00:05:38,541 说它应该。 120 00:05:38,541 --> 00:05:41,290 然后你需要提取的东西 所谓的查询中,出来的东西 121 00:05:41,290 --> 00:05:44,200 问号之后,像 我们看到我们的谷歌的例子 122 00:05:44,200 --> 00:05:46,320 在传递一个HD参数。 123 00:05:46,320 --> 00:05:49,050 然后,我们一起串联 Web服务器的根 124 00:05:49,050 --> 00:05:52,520 与这就是路径 这要求第一行 125 00:05:52,520 --> 00:05:56,010 并形成的完整路径 在文件中,我们要看看的。 126 00:05:56,010 --> 00:06:00,300 >> 此后,我们要确保 该文件存在并且可读。 127 00:06:00,300 --> 00:06:05,100 然后我们要提取其 文件扩展名,将.html或.PHP, 128 00:06:05,100 --> 00:06:09,920 或一些这样的扩展,它是在 请求字符串的最末尾。 129 00:06:09,920 --> 00:06:11,940 接下来是一个整体 一串代码,我们写了 130 00:06:11,940 --> 00:06:15,800 实际生成PHP 为您生成的内容。 131 00:06:15,800 --> 00:06:18,010 概括地说,这 在名称代码采用 132 00:06:18,010 --> 00:06:20,250 该文件你想PHP解释。 133 00:06:20,250 --> 00:06:24,630 我们通过一种叫做传递 管道进入PHP解释器。 134 00:06:24,630 --> 00:06:28,060 找回响应,虽然 所述响应是一个文件本身。 135 00:06:28,060 --> 00:06:32,110 然后我们遍历该文件的 字节,拉他们都到一个缓冲区 136 00:06:32,110 --> 00:06:34,180 这样我们就可以最终 打印出来。 137 00:06:34,180 --> 00:06:37,230 >> 事实上,所有的这些 调用这里dprintf 138 00:06:37,230 --> 00:06:40,110 可以让我们打印的东西 称为文件描述符,其 139 00:06:40,110 --> 00:06:42,350 仅仅是一个整数 表示一个文件。 140 00:06:42,350 --> 00:06:45,360 在精神上非常相似,但 从文件根本不同 141 00:06:45,360 --> 00:06:46,620 明星指针。 142 00:06:46,620 --> 00:06:50,260 请注意,您可以使用类似的语法 这里的printf,这样我可以动态 143 00:06:50,260 --> 00:06:54,000 插入类似的长度 对于HTTP头的值 144 00:06:54,000 --> 00:06:55,270 所谓内容长度。 145 00:06:55,270 --> 00:06:57,990 最终我用了 功能权限,以实际编写 146 00:06:57,990 --> 00:07:00,040 身体向请求。 147 00:07:00,040 --> 00:07:03,750 >> 不幸的是,我们只执行 动态支持 148 00:07:03,750 --> 00:07:05,350 生成的PHP文件。 149 00:07:05,350 --> 00:07:08,520 我们没有实施的支持 静态文件一样的GIF,和JPEG, 150 00:07:08,520 --> 00:07:10,660 和CSS和HTML文件。 151 00:07:10,660 --> 00:07:14,450 ,不幸的是,留给你 以向客户端作出响应的目的 152 00:07:14,450 --> 00:07:15,090 此做。 153 00:07:15,090 --> 00:07:20,050 因此,在那里你会发现,有 不就是块内的很多灵感, 154 00:07:20,050 --> 00:07:23,520 但如果你稍微高了怎么 我们走遍解释PHP代码, 155 00:07:23,520 --> 00:07:25,520 该功能将使用 有一点不同。 156 00:07:25,520 --> 00:07:27,561 >> 事实上,你可以借 一些功能 157 00:07:27,561 --> 00:07:29,620 也许是从取证 习题集,因为 158 00:07:29,620 --> 00:07:32,860 在一天结束时,所有你需要 这里做的是,一旦你知道什么文件打开 159 00:07:32,860 --> 00:07:35,690 一旦你知道这是所谓的 MIME类型或内容类型 160 00:07:35,690 --> 00:07:39,040 需要读取在这些字节 并以某种方式吐出他们回来了。 161 00:07:39,040 --> 00:07:41,190 >> 这和现在之旅 文件的其他功能。 162 00:07:41,190 --> 00:07:43,820 截至第一连接, 它简单地返回true 163 00:07:43,820 --> 00:07:47,350 当它终于听到 来自用户的连接。 164 00:07:47,350 --> 00:07:48,786 接下来是错误。 165 00:07:48,786 --> 00:07:52,296 错误,同时,作为一个功能我们 写来处理所有的不同的400 166 00:07:52,296 --> 00:07:55,360 500 HTTP状态 你可能想码 167 00:07:55,360 --> 00:07:58,500 以发送回用户, 连同一个标准报文。 168 00:07:58,500 --> 00:08:01,950 >> 接下来是负载,特别 肉香功能,其目的在生活中 169 00:08:01,950 --> 00:08:06,920 被从文件中读取星的指针 文件的内容,成为一个全球性的缓冲 170 00:08:06,920 --> 00:08:09,000 我们全局声明 上述[?主力。 ?] 171 00:08:09,000 --> 00:08:12,649 这是一个有点复杂,因为我们 必须从文件中读取的字节 172 00:08:12,649 --> 00:08:14,690 但检查在每次迭代 我们是否已把 173 00:08:14,690 --> 00:08:17,600 命中的文件的末尾或 别的东西出现了问题。 174 00:08:17,600 --> 00:08:21,210 而我们使用realloc的,以确保 无论我们使用缓冲区增长 175 00:08:21,210 --> 00:08:24,440 并不断扩张,总是 字节数的保持领先 176 00:08:24,440 --> 00:08:25,675 我们需要适合在那里。 177 00:08:25,675 --> 00:08:27,550 处理程序,同时, ,获取功能 178 00:08:27,550 --> 00:08:30,630 所谓由具有方式 注册的控制C作为信号 179 00:08:30,630 --> 00:08:32,140 我们要拦截。 180 00:08:32,140 --> 00:08:34,070 请注意这里的处理程序 它最终 181 00:08:34,070 --> 00:08:36,780 电话停机,这当然 停止Web服务器。 182 00:08:36,780 --> 00:08:39,750 不幸的是,查找 未实现。 183 00:08:39,750 --> 00:08:41,940 在精神上,这是一个 很简单的功能。 184 00:08:41,940 --> 00:08:44,900 给定一个文件扩展名,它需要 回到它的所谓的MIME 185 00:08:44,900 --> 00:08:46,320 型或内容类型。 186 00:08:46,320 --> 00:08:49,260 我们在规范中指定 什么映射必须是。 187 00:08:49,260 --> 00:08:52,330 但你需要翻译 它最终为C代码。 188 00:08:52,330 --> 00:08:56,490 >> 接下来是我们同样肉香功能 所谓的解析,在生活中,其目的 189 00:08:56,490 --> 00:08:59,350 是阅读,而不是从文件中, 但是从一个网络连接。 190 00:08:59,350 --> 00:09:03,510 具体来说,读和解析 这是来自浏览器的HTTP请求 191 00:09:03,510 --> 00:09:05,940 到服务器,这样 最终我们可以解析 192 00:09:05,940 --> 00:09:09,530 在刚刚在请求中的报头 行,回到那些你 193 00:09:09,530 --> 00:09:12,720 由全局缓冲器的方式 我们上面的[声明?主力。 ?] 194 00:09:12,720 --> 00:09:14,880 >> 复位,同时,是 函数,我们定义 195 00:09:14,880 --> 00:09:18,730 这被称为内部迭代 主每一次你约 196 00:09:18,730 --> 00:09:20,799 准备开始听 为一个新的连接 197 00:09:20,799 --> 00:09:22,840 让我们总是知道 我们变量的状态 198 00:09:22,840 --> 00:09:24,870 所以,我们也已经 释放任何内存 199 00:09:24,870 --> 00:09:28,070 可能已被分配给 以前的网络连接。 200 00:09:28,070 --> 00:09:30,060 接下来是启动时, 功能我们写 201 00:09:30,060 --> 00:09:31,920 包含整个 大量的网络代码 202 00:09:31,920 --> 00:09:34,420 最终启动Web服务器。 203 00:09:34,420 --> 00:09:36,680 >> 最后上来就是功能 所谓停止,这 204 00:09:36,680 --> 00:09:38,770 正是这么做的,它 停止Web服务器。 205 00:09:38,770 --> 00:09:42,270 但首先,它可以释放任何内存 仍然已经分配。 206 00:09:42,270 --> 00:09:45,850 但它最终调用exit 甚至没有返回控制 207 00:09:45,850 --> 00:09:47,480 我们的主要功能。 208 00:09:47,480 --> 00:09:49,480 最终,所述一个 最重要的技术 209 00:09:49,480 --> 00:09:52,680 当执行该Web服务器 将是一个有点试验和错误的, 210 00:09:52,680 --> 00:09:55,886 有一个浏览器窗口打开 在右侧和在一个终端窗口 211 00:09:55,886 --> 00:09:57,760 离开时,服务器控制台 窗口,这样就 212 00:09:57,760 --> 00:10:00,420 可以看到,有消息 被显示在屏幕上。 213 00:10:00,420 --> 00:10:04,170 >> 但更好的是将第三 窗口中,第二个终端窗口, 214 00:10:04,170 --> 00:10:07,135 在您使用Telnet的使用 对于该规定的规范。 215 00:10:07,135 --> 00:10:09,640 和Telnet仅仅是一个很 简单的网络程序 216 00:10:09,640 --> 00:10:12,660 可以让你假装 是在一个窗口中的浏览器 217 00:10:12,660 --> 00:10:14,540 而谈话的另一个窗口。 218 00:10:14,540 --> 00:10:16,830 这样,您就可以看到 正是文本命令 219 00:10:16,830 --> 00:10:18,700 这都回来了 从服务器到客户端 220 00:10:18,700 --> 00:10:20,810 无需戳 围绕Chrome的开发者 221 00:10:20,810 --> 00:10:24,010 在另外的工具 笨重的接口。 222 00:10:24,010 --> 00:10:29,099