-
项目名称:httpserver服务器
- 项目结构
- 相关知识说明
- 启动程序开发
- 核心程序开发
- 项目结构
本程序要实现在指定目录和端口访问服务器资源,程序核心逻辑较为简单,所以共有三个文件组成,一个是epoll_start.c,为启动程序,一个为epoll_main.c 为核心程序,一个为epoll_main.h。
- 所需知识
IO多路复用(epoll) socket 编程 html基础知识 http协议知识
- 启动程序开发
- #include
- #include
- #include "epoll_func.h"
- #include
- int main(int argc,char * argv[]){
- //判断是不是有端口和启动路径
- if (argc<2)
- {
- printf("Useage ./a.out port path");
- }
- int port = atoi(argv[1]);
- //切换目录
- int ret = chdir(argv[2]);
- if(ret == -1)
- {
- perror("chdir error");
- exit(1);
- }
- //启动服务
- runserver(port);
- return 0;
-
}
- 核心程序开发
//epoll_main.c 调用的就是此处的函数
int runserver(int port){
//开启监听服务
int efd = epoll_create(MAX_EVENTS); //创建epoll树
int lfd = createlfd(port);//创建socket并绑定本地端口
addfdtoevets(efd,lfd); //将lfd添加到epoll树上
//根据内核返回的信息进行处理
while (1)
{
int value = epoll_wait(efd,watchfd,2000,-1); //调用epoll_wait 等内核返回信息
for (int i = 0; i < value; i++) //epoll会返回事件的数量和对应监听的fd,循环判断
{
//判断是否时客户端的读事件
int checkfd = watchfd[i].data.fd;
if (checkfd == lfd) //如果是监听socket获得新的连接
{
//接受请求
struct sockaddr_in clientaddr;
int len = sizeof(clientaddr);
int confd = accept(lfd,(struct sockaddr *)&clientaddr,&len);
int flag = fcntl(confd, F_GETFL);
flag |= O_NONBLOCK;
fcntl(confd, F_SETFL, flag);
addfdtoevets(efd,confd);
}
else //socket的发送了数据,这里我们监听的是读事件
{
//这里是过滤 只处理读取事件
if(! watchfd[i].events & EPOLLIN)
{
continue;
}
printf("the request is comming!!\n");
parsecontent(checkfd,efd); //解析http协议头和方法
}
}
}
}
这里用到了epoll的几个方法,后续单独开一个系列进行阐述,今天先写核心逻辑里的主要代码。