我想从lilin ip摄像机接收mjpeg流。我使用libevent库来建立http连接。主要功能是buildHttpConnect。示例代码如下:
#include <event2/http.h>
#include <event2/http_struct.h>
#define REQUEST_GET_FLAG 3
struct http_request_get {
struct evhttp_uri *uri;
struct event_base *base;
struct evhttp_connection *cn;
struct evhttp_request *req;
};
/************************** Ahead Declare ******************************/
void buildHttpConnect(struct event_base *base, const char *ip);
int start_url_request(struct http_request_get *http_req, int req_get_flag);
void http_requset_get_cb(struct evhttp_request *req, void *arg)
{
struct http_request_get *http_req_get = (struct http_request_get *)arg;
char str[1024];
char timebuffer[80];
gettimebuffer(timebuffer);
sprintf(str, "%s [%i] %s%s?%s\r\n", timebuffer, req == NULL ? -1 : req->response_code, evhttp_uri_get_host(http_req_get->uri), evhttp_uri_get_path(http_req_get->uri), evhttp_uri_get_query(http_req_get->uri));
Utility::WriteLog(Utility::DEBUG_MSG, str);
inst->appendText(str);
if (req == NULL)return;
switch (req->response_code)
{
case HTTP_OK:
{
struct evbuffer* buf = evhttp_request_get_input_buffer(req);
size_t len = evbuffer_get_length(buf);
printf("print the head info:");
char *tmp = (char*)malloc(len + 1);
memcpy(tmp, evbuffer_pullup(buf, -1), len);
tmp[len] = '\0';
printf("print the body:%s", tmp);
free(tmp);
event_base_loopexit(http_req_get->base, 0);
break;
}
case HTTP_MOVEPERM:
printf("%s", "the uri moved permanently");
break;
case HTTP_MOVETEMP:
{
const char *new_location = evhttp_find_header(req->input_headers, "Location");
struct evhttp_uri *new_uri = evhttp_uri_parse(new_location);
evhttp_uri_free(http_req_get->uri);
http_req_get->uri = new_uri;
start_url_request(http_req_get, REQUEST_GET_FLAG);
return;
}
default:
event_base_loopexit(http_req_get->base, 0);
return;
}
}
int start_url_request(struct http_request_get *http_req, int req_get_flag)
{
if (http_req->cn)
evhttp_connection_free(http_req->cn);
int port = evhttp_uri_get_port(http_req->uri);
port = (port == -1 ? 80 : port);
http_req->cn = evhttp_connection_base_new(http_req->base,
NULL,
evhttp_uri_get_host(http_req->uri),
port);
/**
* Request will be released by evhttp connection
* See info of evhttp_make_request()
*/if (req_get_flag == REQUEST_GET_FLAG) {
http_req->req = evhttp_request_new(http_requset_get_cb, http_req);
}
if (req_get_flag == REQUEST_GET_FLAG) {
const char *query = evhttp_uri_get_query(http_req->uri);
const char *path = evhttp_uri_get_path(http_req->uri);
size_t len = (query ? strlen(query) : 0) + (path ? strlen(path) : 0) + 1;
char *path_query = NULL;
if (len > 1) {
path_query = (char*)calloc(len, sizeof(char));
sprintf(path_query, "%s?%s", path, query);
}
///** Set the header properties */
//evhttp_add_header(http_req->req->output_headers, "Host", evhttp_uri_get_host(http_req->uri));
////evhttp_add_header(http_req->req->output_headers, "Cache-Control", "no-store, no-cache, must-revalidate, pre-check=0, post-check=0, max-age=0");
//evhttp_add_header(http_req->req->output_headers, "Connection", "keep-alive");
evhttp_add_header(http_req->req->output_headers, "Content-Type", "multipart/x-mixed-replace;boundary=--boundarydonotcross");
//"Expires" : "Mon, 3 Jan 2000 12:34:56 GMT",
//evhttp_add_header(http_req->req->output_headers, "Pragma", "no-cache");
evhttp_add_header(http_req->req->output_headers, "Authorization", "Basic YWRtaW46cGFzcw ==");
int ret = evhttp_make_request(http_req->cn, http_req->req, EVHTTP_REQ_GET,
path_query ? path_query : "/");
char str[1024];
char timebuffer[80];
gettimebuffer(timebuffer);
sprintf(str, (ret != 0) ? "%s [X] %s%s\r\n" : "%s [V] %s%s\r\n", timebuffer, evhttp_uri_get_host(http_req->uri), path_query);
Utility::WriteLog(Utility::DEBUG_MSG, str);
inst->appendText(str);
}
return 0;
}
static inline void print_uri_parts_info(const struct evhttp_uri * http_uri)
{
printf("scheme:%s", evhttp_uri_get_scheme(http_uri));
printf("host:%s", evhttp_uri_get_host(http_uri));
printf("path:%s", evhttp_uri_get_path(http_uri));
printf("port:%d", evhttp_uri_get_port(http_uri));
printf("query:%s", evhttp_uri_get_query(http_uri));
printf("userinfo:%s", evhttp_uri_get_userinfo(http_uri));
printf("fragment:%s", evhttp_uri_get_fragment(http_uri));
}
http_request_get *start_http_requset(struct event_base* base, const char *url, int req_get_flag)
{
int len = 0;
if (req_get_flag == REQUEST_GET_FLAG) {
len = sizeof(struct http_request_get);
}
struct http_request_get *http_req_get = (struct http_request_get *)calloc(1, len);
http_req_get->uri = evhttp_uri_parse(url);
print_uri_parts_info(http_req_get->uri);
http_req_get->base = base;
start_url_request(http_req_get, req_get_flag);
return http_req_get;
}
void buildHttpConnect(struct event_base *base, const char *ip)
{
char * account = new char[256];
account = "admin:pass";
//
struct http_request_get *http_req_get = start_http_requset(base,
//"http://x.x.x.x/getimage?credentail=YWRtaW46cGFzcw==",
"http://x.x.x.x/snap480p?credentail=YWRtaW46cGFzcw==",
REQUEST_GET_FLAG);
}
当我将URL“ http://x.x.x.x/snap480p?credentail=YWRtaW46cGFzcw==”传递给函数start_http_requset时,很好。我可以在函数http_requset_get_cb中获得响应代码为HTTP_OK。但是,当我将URL“ http://x.x.x.x/getimage?credentail=YWRtaW46cGFzcw==”传递给函数start_http_requset以获取mjpeg流时,我在函数http_requset_get_cb中获得了所传递变量req的空值。我不知道为什么
有人知道如何解决这个问题吗?谢谢。