基于epoll的web server

转载 2011年01月07日 23:15:00

我根据一个epoll的模型改了一个http server出来。只有129行,还可以精简不少,呵呵。
小测了一下,一秒钟处理了一万了请求。当然这里只是把现成的东西输出。没考虑到发送数据处理。和请求的解析。
注意了,epoll只基于linux 2.6内核的。其他平台不能用。





/*-------------------------------------------------------------------------------------------------
gcc -o httpd httpd.c -lpthread 
author: wyezl
2006.4.28
---------------------------------------------------------------------------------------------------*/

#include <sys/socket.h>
#include <sys/epoll.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <pthread.h>
#include <errno.h>

#define PORT 8888
#define MAXFDS 5000
#define EVENTSIZE 100

#define BUFFER "HTTP/1.1 200 OK/r/nContent-Length: 5/r/nConnection: close/r/nContent-Type: text/html/r/n/r/nHello"

int epfd;
void *serv_epoll(void *p);
void setnonblocking(int fd)
{
    int opts;
    opts=fcntl(fd, F_GETFL);
    if (opts < 0)
    {
          fprintf(stderr, "fcntl failed/n");
          return;
    }
    opts = opts | O_NONBLOCK;
    if(fcntl(fd, F_SETFL, opts) < 0)
    {
          fprintf(stderr, "fcntl failed/n");
          return;
    }
    return;
}

int main(int argc, char *argv[])
{
    int fd, cfd,opt=1;
    struct epoll_event ev;
    struct sockaddr_in sin, cin;
    socklen_t sin_len = sizeof(struct sockaddr_in);
    pthread_t tid;
    pthread_attr_t attr;

    epfd = epoll_create(MAXFDS);
    if ((fd = socket(AF_INET, SOCK_STREAM, 0)) <= 0)
    {
          fprintf(stderr, "socket failed/n");
          return -1;
    }
    setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const void*)&opt, sizeof(opt));

    memset(&sin, 0, sizeof(struct sockaddr_in));
    sin.sin_family = AF_INET;
    sin.sin_port = htons((short)(PORT));
    sin.sin_addr.s_addr = INADDR_ANY;
    if (bind(fd, (struct sockaddr *)&sin, sizeof(sin)) != 0)
    {
          fprintf(stderr, "bind failed/n");
          return -1;
    }
    if (listen(fd, 32) != 0)
    {
          fprintf(stderr, "listen failed/n");
          return -1;
    }

    pthread_attr_init(&attr);
    pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);
    if (pthread_create(&tid, &attr, serv_epoll, NULL) != 0)
    {
          fprintf(stderr, "pthread_create failed/n");
          return -1;
    }

    while ((cfd = accept(fd, (struct sockaddr *)&cin, &sin_len)) > 0)
    {
          setnonblocking(cfd);
          ev.data.fd = cfd;
          ev.events = EPOLLIN | EPOLLET;
          epoll_ctl(epfd, EPOLL_CTL_ADD, cfd, &ev);
          //printf("connect from %s/n",inet_ntoa(cin.sin_addr));
          //printf("cfd=%d/n",cfd);
    }

    if (fd > 0)
          close(fd);
    return 0;
}

void *serv_epoll(void *p)
{
    int i, ret, cfd, nfds;;
    struct epoll_event ev,events[EVENTSIZE];
    char buffer[512];

    while (1)
    {
          nfds = epoll_wait(epfd, events, EVENTSIZE , -1);
          //printf("nfds ........... %d/n",nfds);
          for (i=0; i<nfds; i++)
          {
                if(events[i].events & EPOLLIN)
                {
                    cfd = events[i].data.fd;
                    ret = recv(cfd, buffer, sizeof(buffer),0);
                    //printf("read ret..........= %d/n",ret);

                    ev.data.fd = cfd;
                    ev.events = EPOLLOUT | EPOLLET;
                    epoll_ctl(epfd, EPOLL_CTL_MOD, cfd, &ev);
                }
                else if(events[i].events & EPOLLOUT)
                {
                    cfd = events[i].data.fd;
                    ret = send(cfd, BUFFER, strlen(BUFFER), 0);
                    //printf("send ret...........= %d/n", ret);

                    ev.data.fd = cfd;
                    epoll_ctl(epfd, EPOLL_CTL_DEL, cfd, &ev);
                    //shutdown(cfd, 1);
                    close(cfd);

                }
          }
    }
    return NULL;
}




下面是测试结果:

[yangjian2@localhost bin]$ ./ab -c 50 -n 10000 [url]http://202.108.xxx.xxx:8888/[/url]
This is ApacheBench, Version 2.0.41-dev <$Revision: 1.121.2.12 $> apache-2.0
Copyright (c) 1996 Adam Twiss, Zeus Technology Ltd, [url]http://www.zeustech.net/[/url]
Copyright (c) 1998-2002 The Apache Software Foundation, [url]http://www.apache.org/[/url]

Benchmarking 202.108.xxx.xxx (be patient)
Completed 1000 requests
Completed 2000 requests
Completed 3000 requests
Completed 4000 requests
Completed 5000 requests
Completed 6000 requests
Completed 7000 requests
Completed 8000 requests
Completed 9000 requests
Finished 10000 requests


Server Software:     
Server Hostname:     202.108.xxx.xxx
Server Port:         8888

Document Path:       /
Document Length:     5 bytes

Concurrency Level:     50
Time taken for tests:   0.921732 seconds
Complete requests:     10000
Failed requests:     0
Write errors:       0
Total transferred:     872088 bytes
HTML transferred:     50120 bytes
Requests per second:   10849.14 [#/sec] (mean)
Time per request:     4.609 [ms] (mean)
Time per request:     0.092 [ms] (mean, across all concurrent requests)
Transfer rate:       923.26 [Kbytes/sec] received

Connection Times (ms)
        min mean[+/-sd] median   max
Connect:     1   1   0.9     2     3
Processing:   1   2   0.5     2     4
Waiting:     0   1   0.3     1     3
Total:       4   4   0.2     4     5
WARNING: The median and mean for the initial connection time are not within a normal deviation
    These results are probably not that reliable.

Percentage of the requests served within a certain time (ms)
50%     4
66%     4
75%     4
80%     4
90%     4
95%     4
98%     5
99%     5
100%     5 (longest request)

 

http://blog.sina.com.cn/u/1181509184

基于epoll的简单的http服务器

本人用epoll写了一个简单的http服务器,该服务器在客户端第一次发送数据时可以正确处理,但是当客户端不关闭继续发送数据时,服务器无法读取,请求大家帮忙看看哪里有问题,谢谢server.h/* *...
  • fangjian1204
  • fangjian1204
  • 2014年06月25日 10:04
  • 2638

网络编程(10)基于epoll的服务器实现

关于epoll的相关知识我不就写了,只把我弄的例子写下,我整的这个epoll服务器其实就只是把man epoll中举得那个例子给做完善了。 主要参考了man epoll和百度百科中关于epoll的介绍...
  • xcltapestry
  • xcltapestry
  • 2014年02月16日 23:21
  • 1973

epoll事件处理机制详解

Linux I/O多路复用技术在比较多的TCP网络服务器中有使用,即比较多的用到select函数。Linux 2.6内核中有提高网络I/O性能的新方法,即epoll 。 1、为什么sel...
  • lizhitao
  • lizhitao
  • 2013年07月26日 16:40
  • 1482

一起来写web server 08 -- 多线程+非阻塞IO+epoll

到了多线程,一些东西就变得耐人寻味了. 这个版本是在前面单线程epoll的基础上引入了线程池,当然不是前面玩具一样的线程池,而是一个通用的组件,生产者消费者队列.生产者消费者队列生产者消费者问题是操作...
  • lishuhuakai
  • lishuhuakai
  • 2016年11月04日 10:24
  • 654

一个简单的基于epoll的web server

origin: http://blog.csdn.net/xiaonamylove/article/details/3998365  一个简单的基于epoll的web server,性能...
  • yazhouren
  • yazhouren
  • 2015年07月02日 14:30
  • 287

轻量级的web server

一、背景 web接口是一个应用系统常用的接口,本文所说的轻量级的web server是指应用系统不以web访问为主,web接口提供辅助作用,例如,修改配置等,此时,对web server的要求是程序...
  • guxch
  • guxch
  • 2013年02月20日 08:45
  • 2316

NanoHTTPD web server的一个简单荔枝

【0】README 0.1)本文旨在演示一个简单荔枝,以说明如何使用 NanoHTTPD web server 和 浏览器访问 该server的效果 -----------------------...
  • PacosonSWJTU
  • PacosonSWJTU
  • 2016年02月20日 10:53
  • 984

自己动手编写web server(二)

最近笔者有点忙啊,每天上班,晚上回来写毕业论文,没有太多空闲时间来学东西了。上一篇文章写完,自己读了几遍,感觉笔者的表达能力和文字功底确实垃圾,高考语文也就值103分,没有遗憾!!! 笔者有个习惯,...
  • ZSMJ_2011
  • ZSMJ_2011
  • 2013年10月11日 15:29
  • 1498

大型网站后台架构的Web Server与缓存

1.1 Web server   Web server 用来解析HTTP协议。当web服务器接收到一个HTTP请求时,会返回一个HTTP响应,例如送回一个HTML页面。为了处理一个请求,web服...
  • huangxy10
  • huangxy10
  • 2013年08月13日 09:37
  • 1098

Boa Web Server 缺陷报告及其修正方法

转:http://bbs.chinaunix.net/forum.php?mod=viewthread&tid=824840 综述  Boa 作为一种轻巧实用的 WEB 服务器广泛应用...
  • qq361301276
  • qq361301276
  • 2011年12月26日 11:10
  • 1114
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:基于epoll的web server
举报原因:
原因补充:

(最多只允许输入30个字)