免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 828 | 回复: 0
打印 上一主题 下一主题

自己动手写 HTTP Server [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-09-23 22:47 |只看该作者 |倒序浏览
【 原理 】 一般来说,HTTP Server 也是我们常说的Web服务器,大名鼎鼎的 Apache,还是微软的 IIS (Internet Information Server),开源领域的有 Lighttpd 和最近风头正劲的 Nginx 都是典型的Web服务器。最近想想能不能做一个Web服务器,就提供简单的功能,但是速度很快,能够作为一个专门处理 HTML/CSS/JS/Image 的Web服务器,那样能够让静态资源文件迅速的被访问到,如果有反向代理功能就更帅了,当然了,要是有Cache功能啥的,并且能够编写自定义插件(扩展)就很完美了。。。YY中。。。
基于这个思想,我就花十天时间使用标准C写了一个千行代码小型的HTTP Server,当然目前还不具有反向代理和扩展功能,只是能够简单的支持 HTML/CSS/JS/Image 静态资源文件的访问。HTTP Server 的名字叫做 tmhttpd - TieMa (Tiny&Mini) HTTP Server,小巧,代码少,执行速度快,目前具有的功能包括:   
Support GET/HEAD method
The common MIME types.
Support Self custom default index page
Directory listings.
Support access log
Support Self custom port and max clients
Use fork mode accept new conntion
Support daemon type work
more ..

目前已经发布了 tmhttpd-1.0.0_alpha 版本,包括for Unix/Linux (在 Ubuntu/Fedoar/FreeBSD 下编译通过) 和 在cygwin环境下编译的 for Windows 版本,下面地址有下载:
Unix/Linux:
http://heiyeluren.googlecode.com/files/tmhttpd-1.0.0_alpha.tar.gz

Windows:
http://heiyeluren.googlecode.com/files/tmhttpd-1.0.0_alpha-win32.zip

下面大致来聊聊怎么写一个 HTTP Server,先看看一个HTTP请求的流程:

大致就是 客户端的浏览器(IE、Firefox、Opera、Lynx、Curl、Robot ...) 访问到Web服务器的端口(一般是80),然后端口接受到请求后开始解析请求,如果请求不正确或者非法则直接返回指定的错误代码(可以参考 RFC 1945),如果请求合法,那么就查找相应用户请求的文件,把文件读取后发送给客户端,关闭连接,请求结束。
【 实现 】
贴部分tmhttpd核心代码来描述这个过程:

/**

* 初始化服务器端的Socket连接,等待连接,连接成功后fork新进程处理

*

*/
  
static void InitServerListen( unsigned int port, unsigned int max_client ){
  
    int serversock, clientsock;
  
    struct sockaddr_in server_addr, client_addr;
  
    char currtime[32];
  
  
  
    /* Create the TCP socket */
  
    if ((serversock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP))  0){
  
        die("Failed to create socket");
  
    }
  
  
  
    /* Construct the server sockaddr_in structure */
  
    memset(&server_addr, 0, sizeof(server_addr)); /* Clear struct */
  
    server_addr.sin_family = AF_INET; /* Internet/IP */
  
    server_addr.sin_addr.s_addr = htonl(INADDR_ANY); /* Incoming addr */
  
    server_addr.sin_port = htons(port); /* server port */
  
  
  
    /* Bind the server socket */
  
    if (bind(serversock, (struct sockaddr *) &server_addr, sizeof(server_addr))  0){
  
        die("Failed to bind the server socket");
  
    }
  
    /* Listen on the server socket */
  
    if (listen(serversock, max_client)  0){
  
        die("Failed to listen on server socket");
  
    }
  
  
  
    /* Print listening message */
  
    getdate(currtime);
  
    fprintf(stdout, "[%s] Start server listening at port %d ...\n", currtime, port);
  
    fprintf(stdout, "[%s] Waiting client connection ...\n", currtime);
  
  
  
  
  
    /* Run until cancelled */
  
    while (1){
  
        unsigned int clientlen = sizeof(client_addr);
  
        memset(currtime, 0, sizeof(currtime));
  
        getdate(currtime);
  
  
  
        /* Wait for client connection */
  
        if ((clientsock = accept(serversock, (struct sockaddr *) &client_addr, &clientlen))  0){
  
            die("Failed to accept client connection");
  
        }
  
  
  
        /* Use child process new connection */
  
        if ( fork() == 0 ){
  
            HandleClient(clientsock, client_addr);
  
        } else {
  
            wait(NULL);
  
        }
  
  
  
        /* Not use close socket connection */
  
        close(clientsock);
  
    }
  
  
  
}   
  
%3


本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u2/67414/showart_2058751.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP