前面写过用 Node-Js 写的高并发服务器, 因为Node-Js 基于 异步 非阻塞的机制 ,优点是 容易实现高并发 缺点是 由于是 谷歌V8的引擎 JS 不适合做太大规模的计算操作。
所以 如果 服务器涉及到 大规模的计算操作 并且想 快速开发的话,基于HTTP / TCP IP 协议的话 推荐用 libevent 库 最直观的理解是 基于异步非阻塞的机制就是 都使用了 回调函数
下面的代码是我从之前做过的工程里 找了一段 单独复制出来无法直接运行 我再 从网上找了点相关代码 加以修改
先告诉大家怎么在 Linux 下安装 和 配置 libevent 开发环境
http://download.csdn.net/detail/innovation_miracle/9411914
这个链接是 libevent 的源代码,不要积分的 可以去下载
我的linux环境是 centos 7
把源代码压缩包解压出来
终端 cd 到 源码的目录下
1 . 输入 : ./configure -prefix=/usr/libevent
2. 输入: make
3. 输入: make install
4. 检查是否安装成功 输入: ls -al /usr/lib | grep libevent 如果输出很多 xxxx.so xxxx.3.3.so 代表安装成功了
5. linux下 必须安装 libevent-devel 输入: yum install libevent-devel
6. 最好不要在 windows 平台下用libevent 我之前尝试把linux 平台的服务器代码 移植到 windows 白辛苦几天 不了了之了
7. 推荐一个 我感觉比 vi 好用的编辑器 sublime text 2 有需要的去下载一个
下面 开始写 基于 http 协议的服务器代码
#include
#include
#include
#include
#include // 必须包含 libevent的核心头文件
#include // libevent 提供的http 服务的头文件
#include
void http_req(struct evhttp_request *req,void *arg)
{
char output[2048]="\0";
char tmp[1024];
//获取 访问的请求链接 (使用 evhttp_request_uri or req->uri)
const char *uri;
uri = evhttp_request_get_uri(req);
sprintf(tmp,"uri=%s\n",uri);
strcat(output,tmp);
// 把请求的链接参数 解码
char *decoded_uri;
decoded_uri = evhttp_decode_uri(uri);
//解析url的参数
struct evkeyvalq params;
evhttp_parse_query(decoded_uri,?ms);
sprintf(tmp,"q=%s\n",evhttp_find_header(¶ms,"usrname"));
strcat(output,tmp);
sprintf(tmp,"s=%s\n",evhttp_find_header(¶ms,"password")); // evhttp_find_header 是获取请求链接里特定的字段值
strcat(output,tmp);
free(decoded_uri);
/*
这里可以做很多操作 比如 数据库存储操作 比如memcatch 缓存操作等等
*/
// http 协议头
evhttp_add_header(req->output_headers,"Content-Type","text/plain;charset=UTF-8");
evhttp_add_header(req->output_headers,"Connection","hello world");
struct evbuffer *buf; // 字符缓冲区
buf = evbuffer_new();
evbuffer_add_printf(buf,"It works !\n%s\n",output); // 把结果返回给客户端
evhttp_send_reply(req,HTTP_OK,"OK",buf);
evbuffer_free(buf);
}
int main(int argc, char *argv[])
{
char *http_addr= "127.0.0.1";
char *http_port = 8080;
int http_daemon = 0;
int http_timeout = 120;
if (httpd_daemon)
{
pid_t pid;
pid = fork();
if (pid<0)
{
perror("fork failed");
exit(EXIT_FAILURE);
}
if (pid>0)
{
exit(EXIT_SUCCESS);
}
}
event_init(); // 初始化 event_init 环境 也可以用 struct event_base *base;
struct evhttp *http; // 也可以用 http = evhttp_new(base); 如果调用了 evhttp_new函数 则调用 evhttp_bind_socket 配套使用 我还没试过其他的方式
// 这里直接 调用启动 http 函数
http= evhttp_start(http_addr,http_port);
evhttp_set_timeout(http,http_timeout);
evhttp_set_gencb(http,http_req,NULL); // 加载回调
event_dispatch();
evhttp_free(http);
return 0;
}
gcc libevent_http.c -levent
./a.out
上面的代码不是很完善 需要根据自己的需求进行修改
一般云服务器的带宽是 5MB, 运行上面的代码 可以用apache提供的那个服务器性能的测试工具来测试下 以后有时间讲下 集群部署
下面我会宽泛的 写下 如何 使用 memcatch 和 如何使用 数据库交互 以 mongodb 或者 mysql 为例