基于libevent2.0的ministored的http框架--server端
来源:互联网 发布:易语言充值源码 编辑:程序博客网 时间:2024/04/30 19:15
转自http://blog.csdn.net/sunnydogzhou/article/details/6438122
将Ministored从libevent1.4升级到2.0以后,花了两天额外的时间来做调试这个http的框架。
按照开发的设想,这个ministored支持四个基本的操作put、get、delete、status;在经过几个版本的改动以后,协议如下:
1)数据通过post的方式提交
2)各个基本操作通过一个自定义的Http的头method来区分。而client和server之间的传送的二进制数据通过base64编码以后的字符串发送。数据附加在post操作提交的字符缓冲区中。
2.1 put操作需要的数据key value,解码以后,按照key和value的大小直接二进制拷贝,server并不关心数据的具体类型
2.2 get操作接收client发送的key,解码,取出对应的数据以后,base64编码,发送给client
2.3 delete操作接收client发送的key,解码,删除数据
2.4 status操作直接返回当前Ministore状态的描述字符串
3)各个操作的结果通过自定义的响应头"result"返回
下面是部分的代码,限于篇幅,就不完全展开了。
- #include <event2/event.h>
- #include <event2/buffer.h>
- #include <event2/http.h>
- #include <event2/http_struct.h>
- #include <event2/keyvalq_struct.h>
- #include "base64.h"
- struct ministored_handler_param{
- int key_size;
- int value_size;
- };
- void ministored_handler(struct evhttp_request *req, void *arg){
- struct ministored_handler_param *param = (struct ministored_handler_param *) arg;
- struct evbuffer * buf;
- buf = evbuffer_new();
- const char * ministored_input_opt = evhttp_find_header(req->input_headers,"method");
- fprintf(stdout,"method from client,%s/n",ministored_input_opt);
- evhttp_add_header(req->output_headers,"Content-Type","text/plain");
- evhttp_add_header(req->output_headers,"Connection","keep-alive");
- evhttp_add_header(req->output_headers,"Cache_Control","no-cache");
- if( NULL != ministored_input_opt ){
- if( strcmp(ministored_input_opt,"put") == 0 ){
- int buffer_data_len;
- buffer_data_len = evbuffer_get_length(req->input_buffer);
- if( buffer_data_len > 0 ){
- char * buffer_data = (char * ) malloc(buffer_data_len + 1);
- memset(buffer_data,'/0',buffer_data_len + 1);
- evbuffer_copyout(req->input_buffer,buffer_data,buffer_data_len);
- fprintf(stdout,"data:%s/n",buffer_data);
- fprintf(stdout,"length:%d/n",buffer_data_len);
- char *decoded_data = (char*) malloc (sizeof(char) * 200);
- int decoded_len = decode(buffer_data,buffer_data_len,decoded_data);
- if( NULL != decoded_data){
- char * ministored_key = (char*) malloc( sizeof( char) * (param->key_size + 1) );
- memset(ministored_key,'/0',param->key_size + 1);
- memcpy(ministored_key, decoded_data, param->key_size);
- char *ministored_value = (char*)malloc( sizeof(char) * (param->value_size + 1) );
- memset(ministored_value,'/0', param->value_size + 1);
- memcpy(ministored_value, decoded_data + param->value_size, param->value_size);
- //todo,put into ministore
- long key,value;
- memcpy(&key,ministored_key,8);
- memcpy(&value,ministored_value,8);
- printf("key:%ld/tvaleu:%ld/n",key,value);
- free( ministored_key );
- free( ministored_value );
- evhttp_add_header(req->output_headers,"result","MINISTORED_OK");
- }else{
- evhttp_add_header(req->output_headers,"result","MINISTORED_INTENAL_ERROR");
- }
- free(buffer_data);
- free(decoded_data);
- }else{
- evhttp_add_header(req->output_headers,"result","MINISTORED_NO_DATA");
- }
- }
- if(strcmp(ministored_input_opt,"get")== 0 ){
- ... ...;
- }
- if(strcmp(ministored_input_opt,"delete")== 0 ){
- ... ...;
- }
- if( strcmp(ministored_input_opt,"status" ) == 0){
- int size;
- int used;
- evbuffer_add_printf(buf,"Ministored Simple Service");
- evbuffer_add_printf(buf,"--------------------------");
- evbuffer_add_printf(buf,"size:%d",size);
- evbuffer_add_printf(buf,"used:%d",used);
- }
- evhttp_send_reply(req,HTTP_OK,"OK",buf);
- evbuffer_free(buf);
- }
- }
- void kill_signal(const int sig){
- exit(0);
- }
- void show_help(){
- char *b ="-----------------------------------------"
- "HTTP SIMPLE MiniStore Service /n"
- "-l <ip_addr> IP Address/n"
- "-p <num> TCP Port/n"
- "-d run as a daemon/n";
- fprintf(stderr,b,strlen(b));
- }
- int main(int argc,char **argv){
- char * ministored_listen_ip ="0.0,0.0";
- int ministored_listen_port = 1314;
- bool ministored_daemon = false;
- int ministored_time_out = 3;
- char * ministored_shm_path = "/var/log/temp";
- int ministored_mem_size = 100*1024*1024;
- float ministored_mem_capacity= 0.8;
- int ministored_key_size = 8;
- int ministored_value_size = 8;
- int ministore_work_mode = 1;
- int c;
- while ((c = getopt(argc, argv, "l:p:x:t:s:c:m:i:d:h:k:v")) != -1) {
- switch (c) {
- case 'l':
- ministored_listen_ip = strdup(optarg);
- break;
- case 'p':
- ministored_listen_port = atoi(optarg);
- break;
- case 'd':
- ministored_daemon=true;
- break;
- case 't':
- ministored_time_out = atoi(optarg);
- break;
- case 'k':
- ministored_key_size = atoi(optarg);
- break;
- case 'v':
- ministored_value_size = atoi(optarg);
- break;
- case 'h':
- default:
- show_help();
- }
- }
- // run as deamon
- if( ministored_daemon ){
- pid_t pid;
- pid =fork();
- if( pid < 0 ){
- exit(-1);
- }
- if(pid > 0){
- exit(0);
- }
- }
- signal(SIGPIPE,SIG_IGN);
- signal(SIGINT,kill_signal);
- signal(SIGKILL,kill_signal);
- signal(SIGQUIT,kill_signal);
- signal(SIGTERM,kill_signal);
- signal(SIGHUP,kill_signal);
- struct event_base *base;
- struct evhttp *httpd;
- struct evhttp_bound_socket *handle;
- base = event_base_new();
- if (!base) {
- fprintf(stderr, "Couldn't create an event_base: exiting/n");
- return 1;
- }
- /* Create a new evhttp object to handle requests. */
- httpd = evhttp_new(base);
- if (!httpd) {
- fprintf(stderr, "couldn't create evhttp. Exiting./n");
- return 1;
- }
- evhttp_set_timeout(httpd,ministored_time_out);
- struct ministored_handler_param *param = (struct ministored_handler_param*) malloc(sizeof(struct ministored_handler_param));
- param->key_size = ministored_key_size;
- param->value_size = ministored_value_size;
- // set the call back function
- evhttp_set_gencb(httpd,ministored_handler,param);
- /* Now we tell the evhttp what port to listen on */
- handle = evhttp_bind_socket_with_handle(httpd,ministored_listen_ip , ministored_listen_port);
- if (!handle) {
- fprintf(stderr, "couldn't bind to port %d. Exiting./n",
- (int)ministored_listen_port);
- return 1;
- }
- event_base_dispatch(base);
- evhttp_free(httpd);
- return 0;
- }
这个server框架不仅适用ministored,可以将它搭配任意的存储工具来做网络端的存储。比如BDB、tokyo cabinet来做一个定制的大容量的缓存。
- 基于libevent2.0的ministored的http框架--server端
- 基于libevent2.0的ministored的http框架--server端
- 基于libevent2.0的ministored的http框架--server端
- 基于libevent2.0的ministored的http框架--client端
- 基于libevent2.0的ministored的http框架--client端
- 基于libevent2.0的ministored的http框架--client端
- Ministored--基于libevent的简单网络内存存储
- libevent2.0分析:事件循环的一生
- libevent2.0分析:事件循环的一生
- 基于libevent的http server
- 基于Libevent的HTTP Server
- 基于Libevent的HTTP Server
- libevent2笔记(Timer和Http Client的应用和注意点)
- 基于AndroidAsync框架搭建android http server
- Android基于http的网络请求async-http框架
- libevent2.0源码学习三:对网络模型的(EPOLL)的封装
- libevent2.0源码学习三:对网络模型的(EPOLL)的封装
- 从libevent1.4到libevent2.0碰到的问题,struct evhttp_uri在头文件只有声明
- printf函数的使用方法
- Mahout随机森林算法分布式策略
- Valid Palindrome
- chrome优秀插件推荐
- iis5.1配置.net网站遇到的问题总结
- 基于libevent2.0的ministored的http框架--server端
- 基于libevent2.0的ministored的http框架--client端
- Hibernate的事务和并发
- TCP/IP之链路层
- memcached在windows7上的安装问题
- 菜鸟求职记4
- ajax
- IOC容器在Web容器中的启动
- 我的Android进阶之旅------>Android自定义窗口标题实例