ubuntu c++ http服务端event使用
程序:
#ifndef PLATFROMCOMMUNICATION_H
#define PLATFROMCOMMUNICATION_H
#include <iostream>
#include <fstream>
#include <unistd.h>
#include <curl/curl.h>
#include <net/if.h>
#include <sys/ioctl.h>
#include <arpa/inet.h>
#include <string.h>
#include <event.h>
#include <event2/event.h>
#include <event2/buffer.h>
#include <event2/http.h>
#include <event2/http_struct.h>
#include <event2/http_compat.h>
#include <event2/util.h>
#include <jsoncpp/json/json.h>
#define ETH_NAME "ens33"
#define MYHTTPD_SIGNATURE "MoCarHttpd v0.1"
using namespace std;
class RouteTasks{
public:
RouteTasks();
void init();
private:
static void login(struct evhttp_request *req, void *arg);
string getIp();
int m_port;
int m_timeout;
};
#endif // PLATFROMCOMMUNICATION_H
#include "platfromcommunication.h"
RouteTasks::RouteTasks()
{
m_port = 9000;
m_timeout = 120;
}
void RouteTasks::init()
{
//服务端
//初始化event API
event_init();
//创建一个http server
struct evhttp *httpd;
httpd = evhttp_start(getIp().c_str(), m_port);
evhttp_set_timeout(httpd, m_timeout);
//也可以为特定的URI指定callback
evhttp_set_cb(httpd, "/cgi-bin/entry.cgi/system/login", &RouteTasks::login, NULL);
//循环处理events
event_dispatch();
evhttp_free(httpd);
}
void RouteTasks::login(evhttp_request *req, void *arg)
{
char request_data[4096] = {0};
//获取POST方法的数据
size_t post_size = EVBUFFER_LENGTH(req->input_buffer);
char *post_data = (char *) EVBUFFER_DATA(req->input_buffer);
memcpy(request_data, post_data, post_size);
printf("got control_device_start_stop connection post_data = %s, len =%ld\n", post_data, post_size);
//解析获得的数据
string deviceCode;
string ptz;
Json::Value jvalue;
Json::Reader jreader;
jreader.parse(request_data, jvalue);
deviceCode = jvalue["sUserName"].asString();
ptz = jvalue["sPassword"].asString();
cout<<"============================\n"<<"deviceCode: "<<deviceCode<<" ptz: "<<ptz<<"\n-------------------------\n"<<endl;
//给前段回复一个响应结果
Json::Value root;
Json::FastWriter fastWriter;
root["code"] = Json::Value("200");
root["msg"] = Json::Value("成功");
cout<<"return post"<<fastWriter.write(root)<<endl;
/* 输出到客户端 */
//HTTP header
evhttp_add_header(req->output_headers, "Server", MYHTTPD_SIGNATURE);
evhttp_add_header(req->output_headers, "Content-Type", "application/json; charset=UTF-8");
evhttp_add_header(req->output_headers, "Connection", "close");
//输出的内容
struct evbuffer *buf;
buf = evbuffer_new();
evbuffer_add_printf(buf, "%s", fastWriter.write(root).c_str());
//将封装好的evbuffer 发送给客户端
evhttp_send_reply(req, HTTP_OK, "OK", buf);
evbuffer_free(buf);
}
string RouteTasks::getIp()
{
struct sockaddr_in sin;
struct ifreq ifr;
int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if(sockfd == -1) {
perror("socket error");
return "";
}
strncpy(ifr.ifr_name, ETH_NAME, IFNAMSIZ);
if(ioctl(sockfd, SIOCGIFADDR, &ifr) == 0) {
memcpy(&sin, &ifr.ifr_addr, sizeof (ifr.ifr_addr));
cout<<ETH_NAME<<" ip : "<<inet_ntoa(sin.sin_addr)<<endl;
return inet_ntoa(sin.sin_addr);
}
return "";
}
#include <iostream>
#include "platfromcommunication.h"
using namespace std;
//当向进程发出SIGTERM/SIGHUP/SIGINT/SIGQUIT的时候,终止event的事件侦听循环
void signal_handler(int sig) {
switch (sig) {
case SIGTERM:
case SIGHUP:
case SIGQUIT:
case SIGINT:
event_loopbreak(); //终止侦听event_dispatch()的事件侦听循环,执行之后的代码
break;
}
}
int main()
{
cout<<"hello world"<<endl;
signal(SIGHUP, signal_handler);
signal(SIGTERM, signal_handler);
signal(SIGINT, signal_handler);
signal(SIGQUIT, signal_handler);
RouteTasks rt;
rt.init();
while (1) {
sleep(1);
}
return 0;
}
编译: -levent
由于在ubuntu中https服务端event是阻塞式运行的,所以在正式项目中,可以将其放入线程中,这样不会阻塞程序运行,具体方式如下:上程序
#ifndef PLATFROMCOMMUNICATION_H
#define PLATFROMCOMMUNICATION_H
#include <iostream>
#include <fstream>
#include <unistd.h>
#include <curl/curl.h>
#include <net/if.h>
#include <sys/ioctl.h>
#include <arpa/inet.h>
#include <string.h>
#include <event.h>
#include <event2/event.h>
#include <event2/buffer.h>
#include <event2/http.h>
#include <event2/http_struct.h>
#include <event2/http_compat.h>
#include <event2/util.h>
#include <jsoncpp/json/json.h>
#include <boost/thread.hpp>
#define ETH_NAME "ens33"
#define MYHTTPD_SIGNATURE "MoCarHttpd v0.1"
using namespace std;
class RouteTasks{
public:
RouteTasks();
~RouteTasks();
void init();
private:
static void login(struct evhttp_request *req, void *arg);
static void init_thread(void *arg);
void init_sub();
string getIp();
int m_port;
int m_timeout;
//创建一个http server
struct evhttp *httpd;
};
#endif // PLATFROMCOMMUNICATION_H
#include "platfromcommunication.h"
RouteTasks::RouteTasks()
{
m_port = 7777;
m_timeout = 120;
//初始化event API
event_init();
}
RouteTasks::~RouteTasks()
{
evhttp_free(httpd);
}
void RouteTasks::init()
{
boost::thread t(&RouteTasks::init_thread, this);
}
void RouteTasks::login(evhttp_request *req, void *arg)
{
char request_data[4096] = {0};
//获取POST方法的数据
size_t post_size = EVBUFFER_LENGTH(req->input_buffer);
char *post_data = (char *) EVBUFFER_DATA(req->input_buffer);
memcpy(request_data, post_data, post_size);
printf("got control_device_start_stop connection post_data = %s, len =%ld\n", post_data, post_size);
//解析获得的数据
string deviceCode;
string ptz;
Json::Value jvalue;
Json::Reader jreader;
jreader.parse(request_data, jvalue);
deviceCode = jvalue["sUserName"].asString();
ptz = jvalue["sPassword"].asString();
cout<<"============================\n"<<"deviceCode: "<<deviceCode<<" ptz: "<<ptz<<"\n-------------------------\n"<<endl;
//给前段回复一个响应结果
Json::Value root;
Json::FastWriter fastWriter;
root["code"] = Json::Value("200");
root["msg"] = Json::Value("成功");
cout<<"return post"<<fastWriter.write(root)<<endl;
/* 输出到客户端 */
//HTTP header
evhttp_add_header(req->output_headers, "Server", MYHTTPD_SIGNATURE);
evhttp_add_header(req->output_headers, "Content-Type", "application/json; charset=UTF-8");
evhttp_add_header(req->output_headers, "Connection", "close");
//输出的内容
struct evbuffer *buf;
buf = evbuffer_new();
evbuffer_add_printf(buf, "%s", fastWriter.write(root).c_str());
//将封装好的evbuffer 发送给客户端
evhttp_send_reply(req, HTTP_OK, "OK", buf);
evbuffer_free(buf);
}
void RouteTasks::init_thread(void *arg)
{
RouteTasks* rt = (RouteTasks*)arg;
rt->init_sub();
}
void RouteTasks::init_sub()
{
//服务端
// //初始化event API
// event_init();
// //创建一个http server
// struct evhttp *httpd;
httpd = evhttp_start(getIp().c_str(), m_port);
evhttp_set_timeout(httpd, m_timeout);
//也可以为特定的URI指定callback
evhttp_set_cb(httpd, "/cgi-bin/entry.cgi/system/login", &RouteTasks::login, NULL);
//循环处理events
event_dispatch();
// evhttp_free(httpd);
}
string RouteTasks::getIp()
{
struct sockaddr_in sin;
struct ifreq ifr;
int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if(sockfd == -1) {
perror("socket error");
return "";
}
strncpy(ifr.ifr_name, ETH_NAME, IFNAMSIZ);
if(ioctl(sockfd, SIOCGIFADDR, &ifr) == 0) {
memcpy(&sin, &ifr.ifr_addr, sizeof (ifr.ifr_addr));
cout<<ETH_NAME<<" ip : "<<inet_ntoa(sin.sin_addr)<<endl;
return inet_ntoa(sin.sin_addr);
}
return "";
}
#include <iostream>
#include "platfromcommunication.h"
using namespace std;
//当向进程发出SIGTERM/SIGHUP/SIGINT/SIGQUIT的时候,终止event的事件侦听循环
void signal_handler(int sig) {
switch (sig) {
case SIGTERM:
case SIGHUP:
case SIGQUIT:
case SIGINT:
event_loopbreak(); //终止侦听event_dispatch()的事件侦听循环,执行之后的代码
break;
}
}
int main()
{
cout<<"hello world"<<endl;
signal(SIGHUP, signal_handler);
signal(SIGTERM, signal_handler);
signal(SIGINT, signal_handler);
signal(SIGQUIT, signal_handler);
RouteTasks rt;
rt.init();
while (1) {
sleep(1);
}
return 0;
}