Reload Original PagePrint PageEmail Page

用libevent开发一个server | 此处荒无人烟

今天看了一下libevent 这个包,可以简单的实现一个http服务器,大家看代码吧

#include < stdlib.h >
#include < stdio.h >
#include < sys/queue.h >
#include <  time.h >
#include <  string.h >
#include <  err.h  >
#include < event.h >
#include <  evhttp.h >

void now_handler(struct evhttp_request *req,void *arg)
{
    struct evbuffer *buf;
    buf = evbuffer_new();

    if(buf == NULL)
        err(1,"failed to creat response buffer");

    char *decode_uri = strdup((char*)evhttp_request_uri(req));
    struct evkeyvalq http_query;
    evhttp_parse_query(decode_uri,&http_query);
    printf("%s\n\n",decode_uri);
    free(decode_uri);

    const char *http_param = evhttp_find_header(&http_query,"param");
    const char *http_opt = evhttp_find_header(&http_query,"opt");
    const char *http_charset = evhttp_find_header(&http_query,"charset");
    const char *http_data = evhttp_find_header(&http_query,"data");

    printf("%s\n\n",http_param);
    if(http_charset !=NULL){
        char *content_type = (char *)malloc(64);
        memset(content_type,'\0',64);
        sprintf(content_type,"text/plain; charset=%s",http_charset);
        evhttp_add_header(req->output_headers,"Content-Type",content_type);
        free(content_type);
    } else {
        evhttp_add_header(req->output_headers,"Content-Type","text/plain");
    }
    evhttp_add_header(req->output_headers, "Keep-Alive", "120");
    if(strcmp(http_opt,"put") == 0){
        int buffer_data_len;
        buffer_data_len = EVBUFFER_LENGTH(req->input_buffer);
        printf("%d\n\n",buffer_data_len);
        if(buffer_data_len > 0 ){
            char *buffer_data = (char *)malloc(buffer_data_len + 1);
            memset(buffer_data, '\0', buffer_data_len + 1);
            memcpy (buffer_data, EVBUFFER_DATA(req->input_buffer), buffer_data_len);
            printf("%s\n\n",buffer_data);
            evhttp_add_header(req->output_headers,"Content","dfdfdfdfd");
            evbuffer_add_printf(buf,"%s","THIS IS OK");
            free(buffer_data);
        } else {
            evbuffer_add_printf(buf,"%s","END");
        }
    }
    evhttp_send_reply(req, HTTP_OK, "OK", buf);
    evhttp_clear_headers(&http_query);
	evbuffer_free(buf);

}
int main(int argc,char **argv)
{
    struct evhttp *httpd;

    event_init();
    httpd = evhttp_start("0.0.0.0",1218);
    if (httpd == NULL)
    {
        fprintf(stderr,"Start server error:%m\n");
        exit(1);
    }

    evhttp_set_gencb(httpd,now_handler,NULL);

    event_dispatch();

    evhttp_free(httpd);

    return 0;

}

编译的时候要先安装好libevent ,编译的时候用 gcc -levent evhttp.c -o evhttp
运行evhttp 直接./evhttp 就可以了
下面是一个php-client 测试用的

$host = "127.0.0.1";
$port = 1218;
$body = "text_message1";
$query = "/?charset=utf-8&param=test&opt=put";

$fp = fsockopen($host, $port, $errno, $errstr, 1);
if (!$fp)
{
	echo "wront";
	return false;
}
echo "post";
$out = "POST ${query} HTTP/1.1\r\n";
$out .= "Host: ${host}\r\n";
$out .= "Content-Length: " . strlen($body) . "\r\n";
$out .= "Connection: close\r\n";
$out .= "\r\n";
$out .= $body;
fwrite($fp, $out);
echo "write";
$len = -1;

echo "22222";
while (($line = trim(fgets($fp))) != "")
{
	$header .= $line;
	if (strstr($line, "Content-Length:"))
	{
		list($cl, $len) = explode(" ", $line);
	}
	if (strstr($line, "Content"))
	{
		list($content, $content_value) = explode(" ", $line);
	}
	if (strstr($line, "Connection: close"))
	{
		$close = true;
	}
}
if ($len < 0)
{
	return false;
}
$body = @fread($fp, $len);
if ($close) fclose($fp);
var_dump($content_value);
var_dump($body);