免费注册 查看新帖 |

Chinaunix

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

lighttpd-1.4.20源码分析[更新于2009-05-20 在第66楼] [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-02-13 19:10 |显示全部楼层 |倒序浏览
lighttpd-1.4.20源码看了很久了,学习总结本来早就该写了的,只是人懒得很,拖拖拉拉到现在,如果各位看了觉得多少还有那么一点点帮助,我就继续来(当然,总结的东东还是会发在这个帖子内)。

预计总共将有15个左右PDF文件发上来 谢谢各位支持

各基本数据结构的分析整理倒是基本完了 但是lighttpd源码最核心的东西(比如配置信息的加载 比如对客户请求访问的响应 等) 我还没整理完 呵呵
未完 请继续关注



[更新于2009-05-20 在第66楼]

[ 本帖最后由 lenky0401 于 2009-5-20 00:32 编辑 ]

lighttpd-1.4.20源码分析之lighttpd主工作模型.pdf

217.26 KB, 下载次数: 8087

lighttpd-1.4.20源码分析之伸展树.pdf

891.86 KB, 下载次数: 5060

lighttpd-1.4.20源码分析之数据结构.pdf

87.14 KB, 下载次数: 4421

lighttpd-1.4.20源码分析之Array.c源码分析.pdf

79.1 KB, 下载次数: 3879

lighttpd-1.4.20源码分析之Etag.c源码分析.pdf

84.87 KB, 下载次数: 3711

lighttpd-1.4.20源码分析之Stat_cache.c源码分析.pdf

109.04 KB, 下载次数: 3744

lighttpd-1.4.20源码分析之Chunk.c源码分析.pdf

71.7 KB, 下载次数: 3882

lighttpd-1.4.20源码分析之Bitset.c源码分析.pdf

64.08 KB, 下载次数: 3468

lighttpd-1.4.20源码分析之Buffer.c源码分析.pdf

83.73 KB, 下载次数: 4299

论坛徽章:
0
2 [报告]
发表于 2009-02-13 20:49 |显示全部楼层
原帖由 langue 于 2009-2-13 19:22 发表
有点意思。不如就这样写下去吧,以后的更新也发到这个帖。


多谢langue帮我扎起,和大家一起学习,我对lighttpd源码也还有不少部分理解起来成问题。

论坛徽章:
0
3 [报告]
发表于 2009-02-13 22:10 |显示全部楼层
原帖由 kestre1 于 2009-2-13 21:17 发表
文档看了一遍,顶LZ~


谢谢 预计将有15个PDF文件发上来 请关注

论坛徽章:
0
4 [报告]
发表于 2009-02-13 23:13 |显示全部楼层
原帖由 converse 于 2009-2-13 23:05 发表
支持。
结合项目阅读代码是提高编程能力的捷径之一。


converse 你好,多谢你之前的热心帮助。

论坛徽章:
0
5 [报告]
发表于 2009-02-14 23:10 |显示全部楼层
谢谢LS几位 如果看了 有疑问 请跟帖 和大家一起讨论

论坛徽章:
0
6 [报告]
发表于 2009-02-15 23:54 |显示全部楼层
:wink: 嗯

[ 本帖最后由 lenky0401 于 2009-2-15 23:57 编辑 ]

论坛徽章:
0
7 [报告]
发表于 2009-02-17 09:31 |显示全部楼层
原帖由 penguin_vip 于 2009-2-16 23:35 发表

有没有使用方法,编译、调试能,那样学习效果更好!!!



我在看配置信息解析加载的时候 自己实际修改 编译 调试过
你是说 需要把如何修改 编译 调式 写个总结么?

那个和所有linux下程序编译是一样的

论坛徽章:
0
8 [报告]
发表于 2009-02-21 22:10 |显示全部楼层
谢谢大家的支持 最近被老板催得紧 忙着赶毕业论文呢 可怜的小娃。
不过关于lighttpd的文档我仍一直在整理 完成了马上发上来。

论坛徽章:
0
9 [报告]
发表于 2009-03-02 23:50 |显示全部楼层
//by lenky
利用select多路复用I/O的Web服务应用模型

/* 可读、可写、异常三种文件描述符集的申明和初始化。*/
fd_set readfds, writefds, exceptionfds;
FD_ZERO(&readfds);
FD_ZERO(&writefds);
FD_ZERO(&exceptionfds);

int max_fd;

/* socket配置和监听。*/
sock = socket(...);
bind(sock, ...);
listen(sock, ...);

/* 对socket描述符上发生关心的事件进行注册。*/
FD_SET(&readfds, sock);
max_fd = sock;

while(1) {
        int i;
        fd_set r,w,e;
       
        /* 为了重复使用readfds 、writefds、exceptionfds,将它们拷贝到临时变量内。*/
        memcpy(&r, &readfds, sizeof(fd_set));
        memcpy(&w, &writefds, sizeof(fd_set));
        memcpy(&e, &exceptionfds, sizeof(fd_set));
       
        /* 利用临时变量调用select()阻塞等待,等待时间为永远等待直到发生事件。*/
        select(max_fd + 1, &r, &w, &e, NULL);

        /* 测试是否有客户端发起连接请求,如果有则接受并把新建的描述符加入监控。*/
        if(FD_ISSET(&r, sock)){
                new_sock = accept(sock, ...);
                FD_SET(&readfds, new_sock);
                FD_SET(&writefds, new_sock);
                max_fd = MAX(max_fd, new_sock);
        }
        /* 对其它描述符发生的事件进行适当处理。描述符依次递增,最大值各系统有所不同(比如在作者系统上最大为1024),在linux可以用命令ulimit -a查看(用ulimit命令也对该值进行修改)。在freebsd下,用sysctl -a | grep kern.maxfilesperproc来查询和修改。*/
        for(i= sock+1; i<max_fd+1; ++i) {
                if(FD_ISSET(&r, i))
                        doReadAction(i);
                if(FD_ISSET(&w, i))
                        doWriteAction(i);
        }
}


利用poll多路复用I/O的Web服务应用模型
/* 新建并初始化文件描述符集。*/
struct pollfd fds[MAX_NUM_FDS];
int max_fd;

/* socket配置和监听。*/
sock = socket(...);
bind(sock, ...);
listen(sock, ...);

/* 对socket描述符上发生关心的事件进行注册。*/
fds[0].fd = sock;
fds[0].events = POLLIN;
max_fd = 1;

while(1) {
        int i;
       
        /*调用poll()阻塞等待,等待时间为永远等待直到发生事件。*/
        poll(fds, max_fd, -1);

        /* 测试是否有客户端发起连接请求,如果有则接受并把新建的描述符加入监控。*/
        if(fds[0].revents & POLLIN){
                new_sock = accept(sock, ...);
                fds[max_fd].fd = new_sock;
                fds[max_fd].events = POLLIN | POLLOUT;
                ++ max_fd;
        }
        /* 对其它描述符发生的事件进行适当处理。*/
        for(i=1; i<max_fd+1; ++i) {
                if(fds.revents & POLLIN)
                        doReadAction(i);
                if(fds.revents & POLLOUT)
                        doWriteAction(i);
        }
}

利用epoll多路复用I/O的Web服务应用模型
/* 新建并初始化文件描述符集。*/
struct epoll_event ev;
struct epoll_event events[MAX_EVENTS];

/* 创建epoll句柄。*/
int epfd = epoll_create(MAX_EVENTS);

/* socket配置和监听。*/
sock = socket(...);
bind(sock, ...);
listen(sock, ...);

/* 对socket描述符上发生关心的事件进行注册。*/
ev.events = EPOLLIN;
ev.data.fd = sock;
epoll_ctl(epfd, EPOLL_CTL_ADD, sock, &ev);

while(1) {
        int i;
        /*调用epoll_wait()阻塞等待,等待时间为永远等待直到发生事件。*/
        int n = epoll_wait(epfd, events, MAX_EVENTS, -1);
        for(i=0; i<n; ++i) {
                /* 测试是否有客户端发起连接请求,如果有则接受并把新建的描述符加入监控。*/
                if(events.data.fd == sock) {
                        if(events.events & POLLIN){
                                new_sock = accept(sock, ...);
                                ev.events = EPOLLIN | POLLOUT;
                                ev.data.fd = new_sock;
                                epoll_ctl(epfd, EPOLL_CTL_ADD, new_sock, &ev);
                        }
                }else{
                        /* 对其它描述符发生的事件进行适当处理。*/
                        if(events.events & POLLIN)
                                doReadAction(i);
                        if(events.events & POLLOUT)
                                doWriteAction(i);
                }
        }
}

利用kqueue多路复用I/O的Web服务应用模型
/* 新建并初始化文件描述符集。*/
struct kevent changelist[MAX_EVENTS];   
struct kevent eventlist[MAX_EVENTS];
int count = 0;

/* 创建kqueue句柄。*/
int kqfd = kqueue();

/* socket配置和监听。*/
sock = socket(...);
bind(sock, ...);
listen(sock, ...);

/* 对socket描述符上发生关心的事件进行注册。*/
EV_SET(&changelist[0], sock, EVFILT_READ, EV_ADD | EV_ENABLE | EV_CLEAR,
        0, 0, 0);
++ count;

while(1) {
        int i;
        /*调用kevent()阻塞等待,等待时间为永远等待直到发生事件。*/
        int n = kevent(kqfd, changelist, count, eventlist, count, NULL);
        for(i=0; i<n; ++i) {
                /* 测试是否有客户端发起连接请求,如果有则接受并把新建的描述符加入监控。*/
                if(eventlist.ident == sock) {
                        new_sock = accept(sock, ...);
                        EV_SET(&changelist[count], new_sock, EVFILT_READ,
                                EV_ADD | EV_ENABLE | EV_CLEAR, 0, 0, 0);
                        ++ count;
                }else{
                        /* 对其它描述符发生的事件进行适当处理。*/
                        doReadAction(i);
                }
        }
}

利用/dev/poll多路复用I/O的Web服务应用模型
/* 新建并初始化文件描述符集。*/
struct pollfd pfd;
struct pollfd pollfds[MAX_EVENTS];
struct dvpoll dopoll;
int count = 0;

/* 打开/dev/poll设备,创建poll句柄。*/
int dpfd = open("/dev/poll", O_RDWR);

/* socket配置和监听。*/
sock = socket(...);
bind(sock, ...);
listen(sock, ...);

/* 对socket描述符上发生关心的事件进行注册。*/
pfd.fd = sock;
pfd.events = EPOLLIN;
pfd.revents = 0;
write(dpfd, pfd, sizeof(pfd));
++ count;

while(1) {
        int i;
        /*调用ioctl()阻塞等待,等待时间为永远等待直到发生事件。*/
        dopoll.dp_timeout = -1;
        dopoll.dp_nfds = count;
        dopoll.dp_fds = &pollfds;
        int n = ioctl(dpfd, DP_POLL, &dopoll);
        for(i=0; i<n; ++i) {
                /* 测试是否有客户端发起连接请求,如果有则接受并把新建的描述符加入监控。*/
                if(pollfds.fd == sock) {
                        if(pollfds.revents & POLLIN){
                                new_sock = accept(sock, ...);
                                pfd.fd = new_sock;
                                pfd.events = EPOLLIN | POLLOUT;
                                pfd.revents = 0;
                                write(dpfd, pfd, sizeof(pfd));
                                ++ count;
                        }
                }else{
                        /* 对其它描述符发生的事件进行适当处理。*/
                        if(pollfds.revents & POLLIN)
                                doReadAction(i);
                        if(pollfds.revents & POLLOUT)
                                doWriteAction(i);
                }
        }
}

利用rtsig多路复用I/O的Web服务应用模型
/* 新建并初始化关注信号。*/
sigset_t sigset;
siginfo_t siginfo;

sigemptyset(&sigset);
sigaddset(&sigset, SIGRTMIN + 1);
sigaddset(&sigset, SIGIO);


/* socket配置和监听。*/
sock = socket(...);
bind(sock, ...);
listen(sock, ...);

/* 重新设置描述符可读写时发送的信号值。*/
fcntl(sock, F_SETSIG, SIGRTMIN + 1);

/* 对socket描述符设置所有者。*/
fcntl(sock, F_SETOWN, getpid());

/* 启用描述符的信号驱动I/O模式。*/
fcntl(sock, F_SETFL, O_ASYNC | O_NONBLOCK | O_RDWR);

while(1) {
        struct timespec ts;
        ts.tv_sec =  1;
        ts.tv_nsec = 0;
       
        /*调用sigtimedwait()阻塞等待,等待时间1秒。*/
        sigtimedwait(&sigset, &siginfo, &ts);
       
        /* 测试是否有客户端发起连接请求,如果有则接受并把新建的描述符加入监控。*/
        if(siginfo.si_fd == sock) {
                new_sock = accept(sock, ...);
                fcntl(new_sock , F_SETSIG, SIGRTMIN + 1);
                fcntl(new_sock , F_SETOWN, getpid());
                fcntl(new_sock , F_SETFL, O_ASYNC | O_NONBLOCK | O_RDWR);
        }else {
        /* 对其它描述符发生的事件进行适当处理。*/
                doReadAction(i);
        }
}

论坛徽章:
0
10 [报告]
发表于 2009-03-02 23:52 |显示全部楼层
.................

[ 本帖最后由 lenky0401 于 2009-3-3 10:21 编辑 ]
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP