基于 libevent 开源框架实现的 web 服务器
分类:
IT文章
•
2023-11-07 19:13:46
/* 原创文章 转载请附上原链接: https://www.cnblogs.com/jiujue/p/10707153.html */
自己实现的如有缺漏欢迎提出
直接代码 一切皆在代码中
首先是 主函数文件 和 头文件
头文件:
1 #ifndef _HEAD_H_
2 #define _HEAD_H_
3
4 #include<stdio.h>
5 #include<string.h>
6 #include<stdlib.h>
7 #include<time.h>
8 #include<math.h>
9 #include <fcntl.h>
10 #include <ctype.h>
11 #include <dirent.h>
12 #include <unistd.h>
13 #include <event2/event.h>
14 #include <event2/listener.h>
15 #include <event2/bufferevent.h>
16 #include <sys/socket.h>
17 #include <sys/types.h>
18 #include <sys/stat.h>
19 #include <arpa/inet.h>
20
21 int judge_type_dir_or_nondir(const char* name);
22 int send_dir_asheml(struct bufferevent *bufev, char *dirname, void *arg);
23 struct evconnlistener* libev_start(struct event_base*base, const char* Ip,int Port);
24 int send_html_head(struct bufferevent* bufev, int stat_no, const char* stat_desc, char* type);
25 const char *get_file_type(const char *name);
26 int send_file(struct bufferevent *bufev,char* file);
27
28 #endif
View Code
主函数文件:
1 // File Name: main.c
2 // Author: jiujue
3 // Created Time: 2019年04月05日 星期五 19时54分48秒
4
5 #include "head.h"
6
7 int main(int argc, const char* argv[])
8 {
9 if(argc < 4)
10 {
11 printf("argument not enough
eg:./app Ip Port sourceDir
");
12 exit(1);
13 }
14
15
16 int ret = chdir(argv[3]);
17 if(-1 == ret)
18 {
19 perror("chdir error");
20 exit(1);
21 }
22 else
23 {
24 printf("chdir successful,to -> %s
",argv[3]);
25 }
26
27 struct event_base* base = event_base_new();
28
29 struct evconnlistener* listen = libev_start(base,argv[1],atoi(argv[2]));
30
31 event_base_dispatch(base);
32
33 evconnlistener_free(listen);
34 event_base_free(base);
35
36 return 0 ;
37 }
View Code
1 // File Name: _libev.c
2 // Author: jiujue
3 // Created Time: 2019年04月05日 星期五 19时54分08秒
4 #include "head.h"
5 #define PATH_OF_404_ "404.html"
6
7 void read_cb(struct bufferevent* bufev, void* arg)
8 {
9 printf("<<<<<<<<<<<<<<<<<<<<<<<<<<<,,Happen read_cb
");
10 char buf[1024] = {0}, method[12] = {0}, path[1024] = {0}, protocol[12] = {0};
11 bufferevent_read(bufev,buf,sizeof(buf));
12 //printf("-----------------------recv http request :%s
",buf);
13 sscanf(buf,"%s %s %s",method,path,protocol);
14 char *file = path+1;
15 if(0 == (strcmp(path,"/") ) )
16 {
17 file = (char*)"./";
18 }
19
20 int isFile = judge_type_dir_or_nondir(file);
21 printf("fffffffff is %d
",isFile);
22 if(0 == isFile)
23 {//is palin file
24 printf("send file <name>>%s
",file);
25 send_file(bufev,file);
26 }
27 if(isFile == 1){//is dir
28 printf("send dir <name>>%s
",file);
29 send_html_head(bufev,200,"OK",(char*)"text/html");
30 send_dir_asheml(bufev,file,NULL);
31 }
32 else if(-1 == isFile)
33 {//is not found file or directory
34 printf("send 404 <name>>%s
",file);
35 send_file(bufev,PATH_OF_404_);
36 }
37
38 }
39
40 void write_cb(struct bufferevent* bufev, void* arg)
41 {
42 struct sockaddr_in *cli = (struct sockaddr_in*)arg;
43 char buf[1024] = {0};
44 printf("Sent respond to cli,Ip ->%s and Port ->%d
",
45 inet_ntop(AF_INET,&(cli->sin_addr.s_addr), buf,sizeof(buf)),
46 ntohs(cli->sin_port) );
47 }
48
49 void event_cb(struct bufferevent* bufev, short ev, void* arg)
50 {
51 printf("event_cb successful
");
52 if(ev & BEV_EVENT_EOF)
53 {
54 struct sockaddr_in *cli = (struct sockaddr_in*)arg;
55 char buf[1024] = {0};
56 printf("Have client disconnect, Ip ->%s and Port ->%d
",
57 inet_ntop(AF_INET,&(cli->sin_addr.s_addr), buf,sizeof(buf)),
58 ntohs(cli->sin_port) );
59
60 }
61 if(ev & BEV_EVENT_ERROR )
62 {
63 printf("******************************** Happy Error******************************
");
64 }
65 bufferevent_free(bufev);
66 }
67
68 void listener_cb(struct evconnlistener *listener,
69 evutil_socket_t fd, struct sockaddr* cli,
70 int cli_len, void* arg)
71 {
72
73 printf("<<<<<<<<<<<<<<<<<<<<,,,,,,,,, listener_cb successful
");
74 struct event_base* base = (struct event_base*)arg;
75
76 struct bufferevent* bufev = bufferevent_socket_new(base, fd, BEV_OPT_CLOSE_ON_FREE);
77 bufferevent_setcb(bufev, read_cb, write_cb, event_cb,cli);
78 bufferevent_enable(bufev,EV_READ);
79
80 }
81
82
83 struct evconnlistener* libev_start(struct event_base*base, const char* Ip,int Port)
84 {
85
86 struct sockaddr_in ser;
87 ser.sin_family = AF_INET;
88 ser.sin_port = htons(Port);
89 inet_pton(AF_INET,Ip,&(ser.sin_addr.s_addr));
90
91 struct evconnlistener* ret = evconnlistener_new_bind(base, listener_cb, base,
92 LEV_OPT_REUSEABLE | LEV_OPT_CLOSE_ON_FREE, 128,
93 (struct sockaddr *)&ser, sizeof(ser));
94
95 if(ret == NULL)
96 {
97 return NULL;
98 }
99
100 return ret;
101 }