开发 Web 服务器的技巧

发布于 2024-07-20 17:26:14 字数 253 浏览 8 评论 0原文

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

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

所以问题很简单。

  • 你开发过网络服务器吗? (无论哪种语言)
  • 您可以提供哪些陷阱和其他好的技巧

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

After doing some search here, I found next to no questions on developing a web server.

I'm mainly going to be doing this for two reasons. As a side project and to learn more about developing a server program. This is not going to turn into a usable application, more of a learning tool

So the questions are simple.

  • Have you developed a web server? (no matter what language)
  • What are the gotchas and other good tips can you supply

Links to helpful sites are welcome, but don't link to a working project that is open source, since this is about the process of learning.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

思慕 2024-07-27 17:26:14

Web 服务器一开始是一段极其简单的代码:

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

因此代码的轮廓很简单。

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

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

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

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

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

这是基本模式; Web 服务器所做的其他一切只是向这个基本模式添加装饰和附加功能。

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


它几乎没有做任何你真正想要的事情,但是对于简单来说,它很难被击败这个 来自 http://www.commandlinefu.com

$ python -m SimpleHTTPServer

A web server starts out as being an extremely simple piece of code:

  • open a TCP/IP socket on port 80
  • while not terminated
    • wait for connections on that socket
    • when someone sends you HTTP headers
      • find the path to the file
      • copy the file to the socket

So the outline of the code is easy.

Now, you have some complexities to handle:

  • in the simplest version of the code, while you're talking to one browser, all the others can't connect. You need to come up with some way of handling multiple connections.
  • it's often convenient to be able to send out something more than just a static file (although the first HTTP servers did exactly that) so you need to be able to run other programs.

Handling the possibility of multiple connections is also relatively easy, with a number of possible choices.

  • the simplest version (again, this is the way it was done originally) is to have the code that listens to port 80 set up a specific socket for that connection, then fork a copy of itself to handle that one connection. That process runs until the socket is closed, and then terminates. However, that's relatively expensive: a fork takes tens of milliseconds in general, so that limits how fast you can run.
  • The second choice is to create a lightweight process — a/k/a a thread — to process the request.

Running a program is actually fairly easy too. In general, you define a special path to a CGI directory; a URL that has a path through that directory then interprets the path name as the path to a program. The server would then create a subprocess using fork/exec, with STDOUT connected to the socket. The program then runs, sending output to STDOUT, and it is sent on to the client browser.

This is the basic pattern; everything else a web server does is just adding frills and additional functionality to this basic pattern.

Here are some other sources for example code:


It pretty much does nothing of what you really wanted, but for simple it's hard to beat this one from http://www.commandlinefu.com:

$ python -m SimpleHTTPServer

深爱成瘾 2024-07-27 17:26:14

首先,请不要让这成为一个可用的项目 - 为 Web 服务器提供正确的安全性确实很难。

好的,这里有一些需要记住的事情:

  1. 接受的线程
    连接需要移交给
    后台线程尽快
    可能的。
  2. 你不能有一个线程
    对于每一个连接 - 与
    大量的你会用完你的
    线程限制。
  3. 使用某种
    工作线程池来处理你的
    要求。
  4. 确保擦洗
    获取 HTTP GET 时的 URL
    要求。 所以我无法做某事
    喜欢
    http://localhost/../../Users/blah/
    以获得更高级别的访问权限。
  5. 确保您始终设置相关
    内容和哑剧类型。

祝你好运——这真是一份糟糕的工作。

Firstly, please don't let this become a usable project - getting security right for web servers is really hard.

Ok, here are things to keep in mind:

  1. The thread that accepts
    connections needs to hand off to
    background threads as soon as
    possible.
  2. You can't have a thread
    for every single connection - with
    large volumes you'll run out of your
    thread limit.
  3. Use some kind of a
    worker thread pool to handle your
    requests.
  4. Ensure that you scrub
    the URL when you get an HTTP GET
    request. So I couldn't do something
    like
    http://localhost/../../Users/blah/
    to get higher level access.
  5. Ensure you always set the relevant
    content and mime types.

Good luck - this is a hell of a job.

挽容 2024-07-27 17:26:14

网络等都非常标准公平,所以不必太担心。 (几乎任何语言都有几个“即时”示例网络服务器。)

相反,应专注于实际实现 HTTP 规范。 您会惊讶于 a) 您不知道的内容和 b) 有多少本应符合 HTTP 的内容实际上并不符合,但要假装得很好。

然后你会惊奇地发现网络居然还能正常工作。

当您使用完 HTTP 后,就可以享受尝试实现 IMAP 的乐趣了。

The networking et al are pretty standard fair, so don't worry so much about that. (there are several "instant", sample network servers in most any language.)

Instead, focus on actually implementing the HTTP specification. You'll be amazed at a) what you don't know and b) how much things that are supposed to be HTTP compliant, really aren't, but fake it well.

Then you'll marvel that the web works at all.

When you're done with HTTP, enjoy trying to implement IMAP.

剪不断理还乱 2024-07-27 17:26:14

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

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

I wrote a light webserver in Python a few years back, also as a learning project.

The simplest piece of advice I can give, especially as a learning project, is build a core that works, then iterative design on top of that. Don't aim for the moon right off the hop, start very small, then add featuers, refine and continue. I would recommend using a tool that encourages expermentation, like Python, where you can literally type and test code at the same time.

你的笑 2024-07-27 17:26:14

我助教的课程有一个代理任务,所以我想我可以在这里透露一些信息。

因此,您最终将进行大量的标题更改,只是为了让您的生活更轻松。 也就是说,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 结尾。

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

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

The course I TAed had a proxy assignment so I can kind of shed some light here, I think.

So, you're going to end up doing a lot of header changing just to make your life easier. Namely, HTTP/1.0 is wayyy easier to deal with than HTTP/1.1. You don't want to have to deal with managing timeouts and keep-alives and stuff like that. One connection per transaction is easiest.

You're going to be doing lots and lots of parsing. Parsing is hard in C. I'd advise you to write a function that is something like

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

and handle it one line at a time, solely because it's easiest to use the existing C string functions on one line at a time. Also, remember lines are \r\n separated and headers are terminated with a \r\n\r\n.

The main hard thing will be parsing, so long as you can read files everything else will work as expected.

For debugging, you'll probably want to print out headers that are passed around to sanity test them when stuff breaks.

流绪微梦 2024-07-27 17:26:14

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

local-web-server is an example of a simple development web server written in node.js.. It's more reliable and has more features than python -m SimpleHTTPServer

烈酒灼喉 2024-07-27 17:26:14

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

以下是一些教程风格的文章: 1 & 2

I was thinking of starting the same project as a way to learn Python better. There's a BaseHTTPServer class that's a pretty good starting point.

Here's some tutorial-style articles: 1 & 2

浸婚纱 2024-07-27 17:26:14

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

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

祝你好运

I've already developed a web server that runs (Html and PHP) using C language
it's not that complicated you should know how to use TCP/IP Sockets, Thread in order to handle multiple requests, processes fork (you need to create a child for php command line executing (i used execvp))

i think the most strugling part is handling strings in c langage and send POST/GET requests in command line.

Good luck

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文