-
Notifications
You must be signed in to change notification settings - Fork 0
/
HttpServer.cpp
156 lines (121 loc) · 4.34 KB
/
HttpServer.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
/*
* File: HttpServer.cpp
* Author: try
*
* Created on 2011年6月6日, 下午12:24
*/
#include "SocketUtils.h"
#include "HttpServer.h"
#include <arpa/inet.h>
#include <errno.h>
#include <iostream>
#include "logger.h"
using namespace std;
HttpServer::HttpServer(unsigned short int port, HttpServletFactory* servletFactory, Conf* conf) :
address(&defaultAddress), servletFactory(servletFactory), defaultServletFactory(NULL),
socketfd(0), evioSocketPt(&evioSocket), conf(conf?conf:&defaultConf){
memset(&defaultAddress, 0, sizeof(defaultAddress));
defaultAddress.sin_family = AF_INET;
defaultAddress.sin_addr.s_addr = INADDR_ANY;
defaultAddress.sin_port = htons(port);
init();
}
HttpServer::HttpServer(unsigned short int port, HttpServlet* servlet, Conf* conf) :
address(&defaultAddress), socketfd(0), evioSocketPt(&evioSocket),
conf(conf?conf:&defaultConf){
defaultServletFactory = new DefaultHttpServletFactory(servlet);
servletFactory = defaultServletFactory;
memset(&defaultAddress, 0, sizeof(defaultAddress));
defaultAddress.sin_family = AF_INET;
defaultAddress.sin_addr.s_addr = INADDR_ANY;
defaultAddress.sin_port = htons(port);
init();
}
HttpServer::HttpServer(sockaddr_in* address, HttpServletFactory* servletFactory, Conf* conf) :
address(address), servletFactory(servletFactory), defaultServletFactory(NULL),
socketfd(0), evioSocketPt(&evioSocket), conf(conf?conf:&defaultConf){
init();
}
HttpServer::HttpServer(sockaddr_in* address, HttpServlet* servlet, Conf* conf) :
address(address), socketfd(0), evioSocketPt(&evioSocket), conf(conf?conf:&defaultConf){
defaultServletFactory = new DefaultHttpServletFactory(servlet);
servletFactory = defaultServletFactory;
init();
}
HttpServer::~HttpServer() {
if(defaultServletFactory)delete defaultServletFactory;
}
void HttpServer::init(){
//设置请求分发程序相关必须参数
dispatcher.httpServer = this;
dispatcher.evioSocket = &evioSocketPt;
dispatcher.conf = conf;
//忽略一些会让程序中止的信号
signal(SIGPIPE, SIG_IGN);
}
void HttpServer::stop(){
evioSocket.stop();
if(socketfd > 0){
::close(socketfd);
socketfd = 0;
}
}
bool HttpServer::start(){
//生成Socket套节字
socketfd = socket(AF_INET, SOCK_STREAM, 0); //SOCK_CLOEXEC SOCK_STREAM
if (socketfd < 0){
LOG_ERROR("create socket failure, errno:%d", errno);
return false;
}
if(!SocketUtils::setReuseaddr(socketfd)){
LOG_ERROR("set reuseaddr failure, errno:%d", errno);
return false;
}
//将套节字与地址绑定
if (bind(socketfd, (struct sockaddr *)address, sizeof(*address)) < 0) {
LOG_ERROR("bind failure, port:%d, errno:%d", ntohs(address->sin_port), errno);
return false;
}
//在此套节字上监听
if (listen(socketfd, 1024) < 0){
LOG_ERROR("socket listen failure, errno:%d", errno);
return false;
}
//设置Socket模式,设置为非阻塞模式
if(SocketUtils::setNonblock(socketfd) != 0){
LOG_ERROR("set nonblock failure, errno:%d", errno);
return false;
}
//使用libev框架监听Socket事件
//启动socket监听服务
evioSocket.set<HttpServer, &HttpServer::acceptCallback>(this);
evioSocket.start(socketfd, EV_READ);
//启动事件监听
if(!dispatcher.start()){
LOG_ERROR("start dispatcher failure, errno:%d", errno);
return false;
}
LOG_INFO("Listening on %s:%d",inet_ntoa(address->sin_addr),ntohs(address->sin_port));
return true;
}
void HttpServer::acceptCallback(ev::io &evio, int revents){
struct sockaddr_in clientAddr;
socklen_t clientLen = sizeof(clientAddr);
//LOG_WARN("evio.fd:%d", evio.fd);
FD clientfd = accept(evio.fd,(struct sockaddr *)&clientAddr, &clientLen);
if (clientfd < 0){
LOG_WARN("accept failure, socketfd:%d, clientfd:%d, errno:%d", socketfd, clientfd, errno);
return;
}
if(!dispatcher.dispatch(clientfd)){
LOG_WARN("dispatch failure, errno:%d", errno);
}
}
void HttpServer::loop(int flags){
ev::loop_ref loop = ev::get_default_loop();
loop.run(flags);
}
void HttpServer::unloop(ev::how_t how /* = ONE */){
ev::loop_ref loop = ev::get_default_loop();
loop.unloop(how);
}