一个简单的wed服务器SHTTPD(9)————main函数文件,Makefile,头文件
2015-08-12 13:36
579 查看
主函数:
头文件:
Makefile:
书上的代码其实有很多错误,网上下载的源码好像有些地方也是有点怪怪的。编译可以通过,运行的时候,在浏览器上输入主机IP,有显示访问,dowork,但是默认的html没有运行。因为知识还不是很熟练,所以打算再熟悉下HTTP协议,以及学习另一个web服务器。
[code]#include "lcw_shttpd.h" //初始化时服务器的默认配置 extern struct conf_opts conf_para= { "/usr/local/var/www/cgi-bin/",//CGI根目录 "index.html",//默认文件名称 "/usr/local/var/www/",//根文件目录 "/etc/SHTTPD.conf",//配置文件路径和名称 8080, //监听端口 4, //最大客户端数量 3,//超时时间 2//初始化线程数量 }; struct vec _shttpd_methods[] = { {"GET", 3, METHOD_GET}, {"POST", 4, METHOD_POST}, {"PUT", 3, METHOD_PUT}, {"DELETE", 6, METHOD_DELETE}, {"HEAD", 4, METHOD_HEAD}, {NULL, 0} }; /****************************************************** 函数名:sig_int(int num) 参数: 功能:SIGINT信号截取函数 *******************************************************/ static void sig_int(int num) { Worker_ScheduleStop(); return; } /****************************************************** 函数名: 参数: 功能:SIGPIPE信号截取函数 *******************************************************/ static void sig_pipe(int num) { return; } /****************************************************** 函数名:do_listen() 参数: 功能:套接字初始化 *******************************************************/ int do_listen() { struct sockaddr_in server; int ss = -1; int err = -1; int reuse = 1; int ret = -1; // 初始化服务器地址 memset(&server, 0, sizeof(server)); server.sin_family = AF_INET; server.sin_addr.s_addr=htonl(INADDR_ANY); server.sin_port = htons(conf_para.ListenPort); //信号截取函数 signal(SIGINT, sig_int); signal(SIGPIPE, sig_pipe); //生成套接字文件描述符 ss = socket (AF_INET, SOCK_STREAM, 0); if (ss == -1) { printf("socket() error\n"); ret = -1; goto EXITshttpd_listen; } //设置套接字地址和端口复用 err = setsockopt (ss, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)); if (err == -1) { printf("setsockopt SO_REUSEADDR failed\n"); } //绑定IP和套接字描述符 err = bind (ss, (struct sockaddr*) &server, sizeof(server)); if (err == -1) { printf("bind() error\n"); ret = -2; goto EXITshttpd_listen; } //设置服务器侦听队列长度 err = listen(ss, conf_para.MaxClient*2); if (err) { printf ("listen() error\n"); ret = -3; goto EXITshttpd_listen; } ret = ss; EXITshttpd_listen: return ret; } int l_main() { int ss = -1; ss = do_listen(); return 0; } /****************************************************** 函数名:main(int argc, char *argv[]) 参数: 功能:主函数 *******************************************************/ int main(int argc, char *argv[]) { signal(SIGINT, sig_int);//挂接信号 Para_Init(argc,argv);//参数初始化 int s = do_listen();//套接字初始化 Worker_ScheduleRun(s);//任务调度 return 0; }
头文件:
[code]//start from the very beginning,and to create greatness //@author: Chuangwei Lin //@E-mail:979951191@qq.com //@brief: SHTTPD服务器的实现:主要的数据结构 //配置文件的结构// #ifndef _LCW_SHTTP_H_ #define _LCW_SHTTP_H_ #include <stdio.h> #include <getopt.h>//getopt_long()函数所在库函数 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> #include <sys/types.h> #include <sys/stat.h> #include <sys/socket.h> #include <sys/wait.h> #include <sys/time.h> #include <netinet/in.h> // for sockaddr_in #include <netdb.h> // for hostent #include <pthread.h> #include <arpa/inet.h> #include <signal.h> #include <errno.h> // we want to catch some of these after all #include <unistd.h> // protos for read, write, close, etc #include <dirent.h> // for MAXNAMLEN #include <limits.h> #include <getopt.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <ctype.h> #include <stddef.h> #define big_int_t long #define URI_MAX 16384 // Default max request size //线程的状态值 enum { WORKER_INITED,//初始化 WORKER_RUNNING,//正在执行 WORKER_DETACHING,//正在卸载 WORKER_DETACHED,//已经卸载 WORKER_IDEL//空闲 }; struct conf_opts { char CGIRoot[128]; //CGI根目录 char DefaultFile[128]; //默认文件名称 char DocumentRoot[128]; //根文件目录 char ConfigFile[128]; //配置文件路径和名称 int ListenPort; //监听端口 int MaxClient; //最大客户端数量 int TimeOut; //超时时间 int InitClient; //初始化线程数量 }; // HTTP协议的方法 typedef enum SHTTPD_METHOD_TYPE{ METHOD_GET, //GET方法 METHOD_POST, //POST方法 METHOD_PUT, //PUT方法 METHOD_DELETE, //DELETE方法 METHOD_HEAD, //HEAD方法 METHOD_CGI, //CGI方法 METHOD_NOTSUPPORT }SHTTPD_METHOD_TYPE; enum {HDR_DATE, HDR_INT, HDR_STRING};//HTTP头部类型 typedef struct shttpd_method { SHTTPD_METHOD_TYPE type; int name_index; }shttpd_method; typedef struct vec { char* ptr;//字符串 int len;//字符串长度 SHTTPD_METHOD_TYPE type;//字符串表示类型 }vec; struct http_header { int len; //Header name length int type; // Header type size_t offset; // Value placeholder char* name; // Header name }; // This structure tells how HTTP headers must be parsed. // Used by parse_headers() function. #define OFFSET(x) offsetof(struct headers, x) union variant { char* v_str; int v_int; big_int_t v_big_int; time_t v_time; void (*v_func)(void); void *v_void; struct vec v_vec; }; //头部结构 struct headers { union variant cl; //内容长度 union variant ct; //内容类型 union variant connection; //连接状态 union variant ims; //最后修改时间 union variant user; //用户名称 union variant auth; //权限 union variant useragent; //用户代理 union variant referer; //参考 union variant cookie; //Cookie union variant location; //位置 union variant range; //范围 union variant status; //状态值 union variant transenc; //编码类型 }; struct cgi{ int iscgi; struct vec bin; struct vec para; }; struct worker_ctl;//要先声明 struct worker_opts{ pthread_t th; //线程的ID号 int flags; //线程状态 pthread_mutex_t mutex;//线程任务互斥 struct worker_ctl *work;//本线程的总控结构 }; struct worker_conn;//要先声明 //请求结构 struct conn_request{ struct vec req;//请求向量 char *head; //请求头部\0'结尾 char *uri; //请求URI,'\0'结尾 char rpath[URI_MAX];//请求文件的真实地址\0'结尾 int method; //请求类型 //HTTP的版本信息 unsigned long major;//主版本 unsigned long minor;//副版本 struct headers ch;//头部结构 struct worker_conn *conn;//连接结构指针 int err; }; //响应结构 struct conn_response{ struct vec res; //响应向量 time_t birth_time; //建立时间 time_t expire_time;//超时时间 int status; //响应状态值 int cl; //响应内容长度 int fd; //请求文件描述符 struct stat fsate; //请求文件状态 struct worker_conn *conn;//连接结构指针 }; struct worker_conn { #define K 1024 char dreq[16*K]; //请求缓冲区 char dres[16*K]; //响应缓冲区 int cs; //客户端套接字文件描述符 int to; //客户端无响应时间超时退出时间 struct conn_response con_res; struct conn_request con_req; struct worker_ctl *work; //本线程的总控结构 }; struct worker_ctl { struct worker_opts opts;//用于表示线程的状态 struct worker_conn conn;//用于表示客户端请求的状态和值 }; //文件内容的类型格式 struct mine_type{ char* extension;//扩展名 int type;//类型 int ext_len;//扩展名长度 char* mime_type;//内容类型 }; void Para_Init(int argc, char *argv[]); int Request_Parse(struct worker_ctl *wctl); int Request_Handle(struct worker_ctl* wctl); int Worker_ScheduleRun(); int Worker_ScheduleStop(); void Method_Do(struct worker_ctl *wctl); void uri_parse(char *src, int len); struct mine_type* Mine_Type(char *uri, int len, struct worker_ctl *wctl); #define DBGPRINT printf #endif
Makefile:
[code]CFLAGS = -Wall -g LIBS = -lpthread TARGET = lcw_shttpd RM = rm -f OBJS = lcw_shttpd_parameters.o lcw_shttpd.o lcw_shttpd_worker.o lcw_shttpd_uri.o lcw_shttpd_request.o lcw_shttpd_method.o lcw_shttpd_mine.o lcw_shttpd_error.o all:$(OBJS) gcc -o $(TARGET) $(OBJS) $(LIBS) clean: $(RM) $(TARGET) $(OBJS)
书上的代码其实有很多错误,网上下载的源码好像有些地方也是有点怪怪的。编译可以通过,运行的时候,在浏览器上输入主机IP,有显示访问,dowork,但是默认的html没有运行。因为知识还不是很熟练,所以打算再熟悉下HTTP协议,以及学习另一个web服务器。
相关文章推荐
- Post方法调用公司发Mail的接口
- 关于List contains方法的一些使用心得
- Hdu 2015 Multi-University Training Contest7
- IO操作演示(DataInputStream、DataOutputStream)
- leetCode #70 Climbing Stairs
- hdu4770:Lights Against Dudely(回溯 + 修剪)
- await/signal/lock实现生产消费者模式
- wait/notify实现生产消费者模式
- CoreData之条件查询 contains
- LeetCode题解:Contains Duplicate II
- CoreData之条件查询 contains
- LeetCode题解:Contains Duplicate
- Dynamics CRM 开启EmailRouter日志记录
- Dynamics CRM 开启EmailRouter日志记录
- Dynamics CRM 开启EmailRouter日志记录
- Dynamics CRM 开启EmailRouter日志记录
- 再谈应用环境下的TIME_WAIT和CLOSE_WAIT
- 新型程序设计语言:Braise语言!
- HDU 3394 双连通分量 桥 Railway
- Contains Duplicate III