[Web Server](一)Tiny Web Server分析

写在前面:

计划写一个Web 服务器,在小组的群博上没有找到相关的文章,自己打算从开始记录下这个过程,一是整理清楚我的构建过程,二是也能让后面的同学做一下参考。

CSAPP上网络编程那一章最后实现了一个小但是功能较齐全的Web 服务器,叫做TINY。因为只是知道HTTP协议的一些概念,还不太清楚一个Web服务器的工作流程和代码组织结构,而书上给出了 Tiny Server 的完整实现,代码非常短,只有几百行,所以自己模仿着手撸了一遍,并试着分析了代码,运行了一下,给自己一个直观的认识。源代码放在 这里,加注释的代码放在这里。接下来分析下这个Tiny Web服务器。

PS:WEB基础就不写了,自己了解下基本的概念,那么看起代码来就足够了。

CSAPP上面的例子用到的一些通用的函数都放在csapp.h头文件中,并在csapp.c中给出实现。我们看到的大写首字母开头的函数,是在原功能函数上面加上了错误处理,比如

pid_t Fork(void) 
{  
     pid_t pid;

     if ((pid = fork()) < 0)
         unix_error("Fork error");
     return pid;
}  

(一) main 函数

监听命令行中传来的端口上的连接请求,通过 Open_listenfd 函数打开一个监听套接字,执行无限循环,不断接受连接请求,执行HTTP事务,执行完毕后关掉连接。

Tiny是个单线程的,Server在处理一个客户请求的时候无法接受别的客户,这在实际应用中是肯定不允许的。解决方法有

  1. 多进程:accept 之后 fork,父进程继续 accept,子进程来处理这 connfd。这样在高并发下,存在几个问题:
    问题1:每次来一个连接都 fork 开销太大。可以查一下调用 fork 时系统具体做了什么,注意一下复制父进程页表的操作。
    问题2:并发量上来后,进程调度器压力太大,进程切换开销非常大。
    问题3:高负载下,消耗太多内存,此外高并发下,进程间通信带来的开销也不能忽略。

  2. 多线程:accept 之后开线程来处理连接。这样解决了 fork 的问题,但是问题2和3还是无法解决。

  3. 线程池:线程数量固定。线程池简介和C++11实现 。这样可以解决以上几个问题。
int main(int argc, char **argv)
{
    int listenfd, connfd, clientlen;

    struct sockaddr_in clientaddr;

    if(argc != 2){
        fprintf(stderr, "Usage: %s <port>\n",argv[0]);
        exit(1);
    }

    //port = atoi(argv[1]);
    listenfd = Open_listenfd(argv[1]);

    while(1){
        clientlen = sizeof(clientaddr);
        connfd = Accept(listenfd, (SA *)&clientaddr, &clientlen);
        doit(connfd);
        Close(connfd);
    }
}

(二)doit 函数

doit 函数处理一个 HTTP 事务。首先读取并解析请求行,用到 rio_readlineb 函数,请参考 用RIO包健壮地读写 。接下来分别解析出 method 、uri 、version,TINY只支持 GET 方法,如果是其他的方法,则调用 clienterror 函数 返回一个错误信息。

TINY不使用请求报头中的任何信息,接下来读取并忽略这些报头。

接下来解析 uri ,将 uri 解析为 文件名 和CGI 参数字符串。并得到请求的是静态内容还是动态内容。

如果没找到这个文件,那么发送一个错误信息给客户端并返回。

如果是请求静态内容,那么首先确认是普通文件并判断是否有读的权限,如果都OK,那么调用 serve_static 函数提供静态内容。类似,调用 serve_dynamic 函数提供动态内容。

/* $begin doit */
void doit(int fd) 
{
    int is_static;
    struct stat sbuf;
    char buf[MAXLINE], method[MAXLINE], uri[MAXLINE], version[MAXLINE];
    char filename[MAXLINE], cgiarg
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值