libevent 作为开源的以事件为驱动的处理框架,有着广阔的用途。
int httpserver_bindsocket(int port, int backlog);//绑定端口
int httpserver_start(int port, int nthreads, int backlog);//server 开始
void* httpserver_Dispatch(void *arg);//等待事件发生
void httpserver_GenericHandler(struct evhttp_request *req, void *arg);//事件发生句柄
void httpserver_ProcessRequest(struct evhttp_request *req);//处理事件
void initDBConfig();//初始化数据库参数
char * db_ip;//查询数据库ip
char * db_name;//查询数据库登陆name
char * db_psd;//数据库登陆密码
int db_port;//数据库服务器端口
char * t_name;//数据库name
服务器所用到的数据库为mysql,直接使用mysql自带接口。程序运行时先初始化数据库参数。
运行时,先开启处理线程
int httpserver_start(int port,const int nthreads, int backlog)
{
int r, i;
int nfd = httpserver_bindsocket(port, backlog);
if (nfd < 0)
return -1;
pthread_t ths[500];//处理线程
for (i = 0; i < nthreads; i++) {
struct event_base *base = event_base_new();
if (base == NULL)
return -1;
struct evhttp *httpd = evhttp_new(base);
if (httpd == NULL)
return -1;
r = evhttp_accept_socket(httpd, nfd);
if (r != 0)
return -1;
evhttp_set_gencb(httpd, httpserver_GenericHandler, NULL);
r = pthread_create(&ths[i], NULL, httpserver_Dispatch, base);
if (r != 0)
return -1;
}
for (i = 0; i < nthreads; i++) {
pthread_join(ths[i], NULL);
}
return 0;
}
绑定端口:
int httpserver_bindsocket(int port, int backlog) {
#ifdef WIN32
init_win_socket();
#endif
int r;
int nfd;
nfd = socket(AF_INET, SOCK_STREAM, 0);
if (nfd < 0) return -1;
int one = 1;
r = setsockopt(nfd, SOL_SOCKET, SO_REUSEADDR, (char *)&one, sizeof(int));//设置端口复用
struct sockaddr_in addr;
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
//addr.sin_addr.s_addr = INADDR_ANY;
addr.sin_port = htons(port);
r = bind(nfd, (struct sockaddr*)&addr, sizeof(addr));
if (r < 0) return -1;
r = listen(nfd, backlog);
if (r < 0) return -1;
//设置非阻塞
#ifdef WIN32
unsigned long flags = 1;
if (ioctlsocket(nfd,FIONBIO,&flags) < 0)
return -1;
#else
int flags;
if ((flags = fcntl(nfd, F_GETFL, 0)) < 0
|| fcntl(nfd, F_SETFL, flags | O_NONBLOCK) < 0)
return -1;
#endif
return nfd;
}
事件处理:
void httpserver_GenericHandler(struct evhttp_request *req, void *arg)
{
httpserver_ProcessRequest(req);//处理句柄
}
具体实现代码: 点击打开链接