10

在这里做了一些搜索之后,我发现几乎没有关于开发 Web 服务器的问题。

我这样做主要有两个原因。作为一个附带项目并了解有关开发服务器程序的更多信息。这不会变成一个可用的应用程序,更多的是一个学习工具

所以问题很简单。

  • 你开发过网络服务器吗?(不管是什么语言)
  • 你能提供什么陷阱和其他好的提示

欢迎链接到有用的网站,但不要链接到开源的工作项目,因为这是关于学习的过程。

4

8 回答 8

19

Web 服务器最初是一段极其简单的代码:

  • 在端口 80 上打开 TCP/IP 套接字
  • 虽然没有终止
    • 等待该套接字上的连接
    • 当有人向您发送 HTTP 标头时
      • 找到文件的路径
      • 将文件复制到套接字

所以代码的大纲很简单。

现在,您需要处理一些复杂性:

  • 在最简单的代码版本中,当您与一个浏览器交谈时,所有其他浏览器都无法连接。您需要想出一些方法来处理多个连接。
  • 能够发送比静态文件更多的东西通常很方便(尽管第一个 HTTP 服务器就是这样做的),因此您需要能够运行其他程序。

处理多个连接的可能性也相对容易,有多种可能的选择。

  • 最简单的版本(同样,这是它最初的方式)是让监听端口 80 的代码为该连接设置一个特定的套接字,然后派生一个自身的副本来处理该连接。该进程一直运行到套接字关闭,然后终止。然而,这相对昂贵:一个分叉通常需要几十毫秒,所以这限制了你可以运行的速度。
  • 第二种选择是创建一个轻量级进程——a/k/aa线程——来处理请求。

运行程序实际上也相当容易。通常,您定义一个 CGI 目录的特殊路径;具有通过该目录的路径的 URL 然后将路径名称解释为程序的路径。然后,服务器将使用 fork/exec 创建一个子进程,并将 STDOUT 连接到套接字。然后程序运行,将输出发送到 STDOUT,然后发送到客户端浏览器。

这是基本模式;Web 服务器所做的所有其他事情都只是为这个基本模式添加了装饰和附加功能。

以下是示例代码的其他一些来源:


它几乎没有你真正想要的,但简单来说很难从http://www.commandlinefu.com击败这个

$ python -m SimpleHTTPServer

于 2009-05-16T18:36:00.713 回答
10

首先,请不要让它成为一个可用的项目 - 为 Web 服务器获得正确的安全性真的很难。

好的,请记住以下几点:

  1. 接受连接的线程需要尽快移交给后台线程。
  2. 您不能为每个连接都有一个线程 - 大量的您将用完您的线程限制。
  3. 使用某种工作线程池来处理您的请求。
  4. 确保在收到 HTTP GET 请求时清理 URL。所以我不能做类似 http://localhost/../../Users/blah/的事情 来获得更高级别的访问权限。
  5. 确保始终设置相关的内容和 mime 类型。

祝你好运——这是一份非常棒的工作。

于 2009-05-16T18:34:23.307 回答
2

网络等是相当标准的公平,所以不要太担心。(有几个“即时”,大多数任何语言的示例网络服务器。)

相反,专注于实际实现 HTTP 规范。你会惊讶于 a) 你不知道什么和 b) 有多少东西应该是符合 HTTP 的,实际上不是,但假装得很好。

然后你会惊叹于网络的工作原理。

使用完 HTTP 后,请享受尝试实现 IMAP 的乐趣。

于 2009-05-16T18:33:54.523 回答
1

几年前我用 Python 写了一个轻量级的网络服务器,也是一个学习项目。

我能给出的最简单的建议,尤其是作为一个学习项目,是构建一个可以工作的核心,然后在此之上进行迭代设计。不要马上就瞄准月亮,从很小的地方开始,然后添加特征,完善并继续。我建议使用鼓励实验的工具,例如 Python,您可以在其中同时输入和测试代码。

于 2009-05-16T18:34:05.257 回答
1

我 TAed 的课程有一个代理作业,所以我想我可以在这里有所启发。

所以,你最终会做很多标题更改,只是为了让你的生活更轻松。也就是说,HTTP/1.0 比 HTTP/1.1 更容易处理。您不想处理管理超时和保持活动以及类似的事情。每个事务一个连接是最简单的。

你会做很多很多的解析。在 C 中解析很难。我建议你编写一个类似的函数

int readline(char *buff, int maxLen) {
    while((c = readNextCharFromSocket(&s)) && c != '\n' && i < maxLen)
      buff[i++] = c;
    return i;
}

并一次处理一行,仅仅是因为一次一行使用现有的 C 字符串函数是最简单的。此外,请记住行是 \r\n 分隔的,并且标题以 \r\n\r\n 终止。

主要的难点是解析,只要您可以读取文件,其他一切都会按预期工作。

对于调试,您可能希望打印出传递的标头,以便在出现问题时对其进行健全性测试。

于 2009-05-16T21:44:17.140 回答
1

local-web-server是一个用 node.js 编写的简单开发 Web 服务器的示例。它比它更可靠并且具有更多功能python -m SimpleHTTPServer

于 2014-05-08T20:55:33.960 回答
0

我正在考虑启动同一个项目作为更好地学习 Python 的一种方式。有一个BaseHTTPServer 类是一个很好的起点。

这里有一些教程式的文章:1 & 2

于 2009-05-16T18:31:35.590 回答
0

我已经开发了一个使用 C 语言运行(Html 和 PHP)的 Web 服务器,它并不复杂你应该知道如何使用 TCP/IP 套接字、线程来处理多个请求、进程分叉(你需要创建一个孩子用于执行 php 命令行(我使用了 execvp))

我认为最困难的部分是在 C 语言中处理字符串并在命令行中发送 POST/GET 请求。

祝你好运

于 2015-01-03T03:26:31.980 回答