HTTP服务器编程

6

我正在尝试编写自己的HTTP 1.1服务器,只是为了好玩并更多地了解HTTP、套接字和线程。

我已经开始了静态页面的交付(使用C语言,目前我希望继续使用它)。我有一个测试页面,根据Chrome的说法,在不使用线程或保持活动套接字的情况下,可以在124毫秒内交付其大约50个文件。

我发现很难使线程/保持活动完全工作。在网络上几乎没有任何资源(在我数小时的谷歌搜索中找不到),详细解释保持活动连接。如果有人能推荐一本关于HTTP服务器编程的好书,我将非常感激。

我以前通过制作简单的聊天程序来进行过一些线程和套接字编程,因此我至少有一些经验。

我的问题是,当我尝试合并线程时,客户端浏览器会建立多个连接。在某个地方,服务器混淆了,客户端只是坐在那里等待响应,而服务器停止做任何事情。我发送Connection:Keep-Alive标头,但这并没有改变任何内容,当我合并keep-alive并创建一个用于在线程函数中获取请求的循环时,它会停顿直到连接关闭。

如果有人能给我一些伪代码,告诉我如何使保持活动/线程为此工作,以便客户端停止同时创建多个连接,我将不胜感激。

下面是正在发生的事情的简要描述:

主函数

 load in static pages to large array of fileinfo struct that hold the file data and length  
 create the socket
 set it to listen to port 80
 set it to listen for 10 connections at a time(i know this is low...)
 start an endless loop
      block while waiting for someone to connect
      check if it's a localhost connection
          shutdown the server
      otherwise
           start a thread(with pthread), sending it the socket variable
 loop


线程函数

 setsock opt for 3 sec timeout on send/recv and enable Keep-alive  
 start endless loop
    read in request  
    if request timed out, break the loop  
    Validate Request function call  
    Create Reponse function call  
    Send response  
    if request contained Connection: close header break the loop  
loop  
close socket  
return


1
RFC2616怎么样?http://tools.ietf.org/html/rfc2616#section-8.1 - Steve-o
你确定这是一个与线程有关的问题吗?另外,你是否设置了Content-Length头?我认为这对于保持连接工作是必需的(除非你使用分块)。 - Alex Jasmin
我能想到的唯一明显的保持连接/线程问题是,您必须按照发出请求的顺序响应流水线请求。因此,如果您坐在读取套接字并将每个请求移交给辅助线程进行处理,请确保正确同步写入。此外,客户端通常会创建多个连接,有或没有持久性。RFC说每个客户端2个,但我认为更多是常见的(Firefox中network.http.max-persistent-connections-per-server的值为6),而且服务器需要支持来自代理的更多连接。 - Steve Jessop
1
我可以给出一个简短的实现描述,但在这个评论框中看起来很丑。我会添加到主帖中。 - Wolftousen
1
搞定了。问题根本不是时间问题,而是线程和未能以线程安全的方式传递套接字变量有关。 - Wolftousen
显示剩余5条评论
3个回答

2
我建议看一下GNU libmicrohttpd。它专注于提供一个框架来构建HTTP 1.1服务器。它很小,并支持有线程和无线程的keep-alive。(个人使用时不使用线程。它还有几种线程模型。)
即使你决定从头开始编写自己的Web服务器,我也建议看一下libmicrohttpd,以便更好地理解协议的工作原理以及库如何以非常清晰的方式模拟Web服务器的“工作流程”。我认为想象keep-alive意味着线程是一个错误的想法,这会妨碍对keep-alive的理解。
(关于Apache作为Web服务器的功劳,它非常庞大,其中有许多与协议无关的功能,而是像其插件系统等等。)

1
我建议获取Apache的源代码并查看他们如何处理它。 当您可以看到实际操作时,伪代码没有太多意义。

我们的答案必须通过管道 :) - James Branigan

1

也许你可以查看Apache的代码以获取一些线索。它是用C语言编写的。

希望有人能够提供更详细的答案 :)


我尽量避免这样做。前几天我开始尝试,但是筛选出我目前不需要知道的内容和我需要的内容非常耗时。 - Wolftousen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接