实现了一个比Nginx速度更快的HTTP服务器(2)

接下来正式开始设计。我选择了非阻塞IO,epoll的边缘触发模式。先找了个比较完整的使用epoll的一个socket server例子作为参考,然后在它的基础上边修改边做实验。

这个例子比较简单,而且也没有体现出非阻塞IO编程。不过通过它我了解到了epoll的基本使用方法。

为了实现并发通信,我们需要把程序“摊平”。

首先,分析我们的HTTP服务器通信过程用到的变量:

状态

 

Wait for reading

 

Wait for writing

 

次数

 

变量类型

 

非本地变量

 

备注

 

Accept

 

Y

 

N

 

n

 

local

         

Read request

 

Y

 

N

 

n

 

nonlocal

 

Read buf

     

Open file

 

N

 

N

 

n

 

nonlocal

 

文件名

     

Send response header

 

N

 

Y

 

n

 

nonlocal

 

Response header buf

     

Read file -> Send response content

 

N

 

Y

 

n*n

 

nonlocal

 

Read&write buf

Write pos

fd

Sock

 

读满read buf或读到EOF,再发

发送时将read buf

 

Close file

 

N

 

N

 

n

     

fd

     

Close socket

 

N

 

N

 

n

     

sock

   

然后,定义一个结构用于保存这些变量:

struct process {
int sock;
int status;
int response_code;
int fd;
int read_pos;
int write_pos;
int total_length;
char buf[BUF_SIZE];
};

为了简便,我直接用一个全局数组装所有的process:

static struct process processes[MAX_PORCESS];

另外定义每个连接通信过程中的三个状态:

#define STATUS_READ_REQUEST_HEADER 0
#define STATUS_SEND_RESPONSE_HEADER 1
#define STATUS_SEND_RESPONSE 2

之后,就是按部就班地实现主循环、读取request,解析header,判断文件是否存在、检查文件修改时间,发送相应的header和content了。

下面只把程序中跟epoll有关的关键部分贴出来:

main()函数:

使用epoll_create()创建一个epoll fd,注意,这里的listen_sock已经设置为nonblocking(我使用setNonblocking函数)了:

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/wyyzwp.html