Libevent例子(一)
服务器端
#include<stdio.h>
#include<string.h>
#include<errno.h>
#include<event.h>
#include<event2/bufferevent.h> void accept_cb(int fd, short events, void* arg);
void socket_read_cb(bufferevent* bev, void* arg);
void event_cb(struct bufferevent *bev, short event, void *arg);
int tcp_server_init(int port, int listen_num); int main(int argc, char **argv) { int listener = tcp_server_init(, );
if (listener == -) {
perror(" tcp_server_init error ");
return -;
}
struct event_base *base = event_base_new();
//添加监听客户端请求连接事件
struct event *ev_listen = event_new(
base, listener, EV_READ | EV_PERSIST, accept_cb, base);
event_add(ev_listen, NULL);
event_base_dispatch(base);
event_base_free(base);
return ;
} void accept_cb(int fd, short events, void *arg) {
evutil_socket_t sockfd;
struct sockaddr_in client;
socklen_t len = sizeof(client);
sockfd = accept(fd, (struct sockaddr *) &client, &len);
evutil_make_socket_nonblocking(sockfd);
printf("accept a client %d\n", sockfd);
struct event_base *base = (struct event_base *) arg;
bufferevent *bev = bufferevent_socket_new(base, sockfd, BEV_OPT_CLOSE_ON_FREE);
bufferevent_setcb(bev, socket_read_cb, NULL, event_cb, arg);
bufferevent_enable(bev, EV_READ | EV_PERSIST);
} void socket_read_cb(bufferevent *bev, void *arg) {
char msg[];
size_t len = bufferevent_read(bev, msg, sizeof(msg));
msg[len] = '\0';
printf("recv the client msg: %s", msg);
char reply_msg[] = "I have recvieced the msg: ";
strcat(reply_msg + strlen(reply_msg), msg);
bufferevent_write(bev, reply_msg, strlen(reply_msg));
} void event_cb(struct bufferevent *bev, short event, void *arg) { if (event & BEV_EVENT_EOF) {
printf("connection closed\n");
}
else if (event & BEV_EVENT_ERROR) {
printf("some other error\n");
}
//这将自动close套接字和free读写缓冲区
bufferevent_free(bev);
} typedef struct sockaddr SA; int tcp_server_init(int port, int listen_num) {
int errno_save;
evutil_socket_t listener; listener = socket(AF_INET, SOCK_STREAM, );
if (listener == -) {
return -;
} //允许多次绑定同一个地址。要用在socket和bind之间
evutil_make_listen_socket_reuseable(listener); struct sockaddr_in sin;
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = ;
sin.sin_port = htons(port); if (bind(listener, (SA *) &sin, sizeof(sin)) < ) {
goto error;
}
if (listen(listener, listen_num) < ) {
goto error;
} //跨平台统一接口,将套接字设置为非阻塞状态
evutil_make_socket_nonblocking(listener);
return listener; error:
errno_save = errno;
evutil_closesocket(listener);
errno = errno_save;
return -;
}
客户端
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<errno.h>
#include<unistd.h>
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<event.h>
#include<event2/bufferevent.h>
#include<event2/buffer.h>
#include<event2/util.h> int tcp_connect_server(const char *server_ip, int port); void cmd_msg_cb(int fd, short events, void *arg); void server_msg_cb(struct bufferevent *bev, void *arg); void event_cb(struct bufferevent *bev, short event, void *arg); int main(int argc, char **argv) {
if (argc < ) {
printf("please input 2 parameter\n");
return -;
} //两个参数依次是服务器端的IP地址、端口号
int sockfd = tcp_connect_server(argv[], atoi(argv[]));
if (sockfd == -) {
perror("tcp_connect error ");
return -;
} printf("connect to server successful\n");
struct event_base *base = event_base_new();
struct bufferevent *bev = bufferevent_socket_new(
base, sockfd, BEV_OPT_CLOSE_ON_FREE); //监听终端输入事件
struct event *ev_cmd = event_new(
base, STDIN_FILENO, EV_READ | EV_PERSIST, cmd_msg_cb, (void *) bev);
event_add(ev_cmd, NULL); //当socket关闭时会用到回调参数
bufferevent_setcb(bev, server_msg_cb, NULL, event_cb, (void *) ev_cmd);
bufferevent_enable(bev, EV_READ | EV_PERSIST);
event_base_dispatch(base);
printf("finished \n");
return ;
} void cmd_msg_cb(int fd, short events, void *arg) {
char msg[]; int ret = read(fd, msg, sizeof(msg));
if (ret < ) {
perror("read fail ");
exit();
} struct bufferevent *bev = (struct bufferevent *) arg;
//把终端的消息发送给服务器端
bufferevent_write(bev, msg, ret);
} void server_msg_cb(struct bufferevent *bev, void *arg) {
char msg[];
size_t len = bufferevent_read(bev, msg, sizeof(msg));
msg[len] = '\0';
printf("recv %s from server\n", msg);
} void event_cb(struct bufferevent *bev, short event, void *arg) { if (event & BEV_EVENT_EOF) {
printf("connection closed\n");
} else if (event & BEV_EVENT_ERROR) {
printf("some other error\n");
}
//这将自动close套接字和free读写缓冲区
bufferevent_free(bev);
struct event *ev = (struct event *) arg;
//因为socket已经没有,所以这个event也没有存在的必要了
event_free(ev);
} typedef struct sockaddr SA; int tcp_connect_server(const char *server_ip, int port) {
int sockfd, status, save_errno;
struct sockaddr_in server_addr; memset(&server_addr, , sizeof(server_addr)); server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(port);
status = inet_aton(server_ip, &server_addr.sin_addr); if (status == ) { //the server_ip is not valid value
errno = EINVAL;
return -;
} sockfd = ::socket(PF_INET, SOCK_STREAM, );
if (sockfd == -) {
return sockfd;
}
status = ::connect(sockfd, (SA *) &server_addr, sizeof(server_addr));
if (status == -) {
save_errno = errno;
::close(sockfd);
errno = save_errno; //the close may be error
return -;
}
evutil_make_socket_nonblocking(sockfd);
return sockfd;
}
Libevent例子(一)的更多相关文章
- Libevent例子(二)
服务端 #include<netinet/in.h> #include<stdio.h> #include<string.h> #include<event. ...
- libevent学习总结
1. 信息隐藏:看*-internal.h文件 如bufferevent_private结构体在bufferevent_async.c中使用时: static inline struct buffer ...
- libevent源码分析:http-server例子
http-server例子是libevent提供的一个简单web服务器,实现了对静态网页的处理功能. /* * gcc -g -o http-server http-server.c -levent ...
- libevent源码分析:hello-world例子
hello-world是libevent自带的一个例子,这个例子的作用是启动后监听一个端口,对于所有通过这个端口连接上服务器的程序发送一段字符:hello-world,然后关闭连接. /* * gcc ...
- libevent源码分析:signal-test例子
signal-test是libevent自带的一个例子,展示了libevent对于信号事件的处理方法. #include <sys/types.h> #include <event2 ...
- libevent源码分析:time-test例子
time-test例子是libevent自带的一个例子,通过libevent提供的定时事件来实现,间隔固定时间打印的功能. /* * gcc -g -o time-test time-test.c - ...
- [z]Libevent使用例子,从简单到复杂
[z]http://blog.csdn.net/luotuo44/article/details/39670221 本文从简单到复杂,展示如何使用libevent.网上的许多例子都是只有服务器端的,本 ...
- Libevent学习笔记(五) 根据例子学习bufferevent
libevent中提供了一个Hello-world.c 的例子,从这个例子可以学习libevent是如何使用bufferevent的. 这个例子在Sample中 这个例子之前讲解过,这次主要看下buf ...
- 【Networking】Libevent客户端例子
[原]Libevent客户端例子 时间 -- :: luotuo44的专栏 原文 http://blog.csdn.net/luotuo44/article/details/34416429 主题 l ...
随机推荐
- Ubuntu 虚拟机安装几点细节整理
虚拟机或者Wubi安装其实都挺简单的,这里还是再次总结下,给遇到麻烦的同学一点参考. 虚拟机安装 虚拟机直接通过新建-标准-选择镜像,Vmware能够自动识别镜像并进行Easy Install安装,E ...
- 在ASP.NET MVC中以post方式传递数组参数的示例【转】
最近在工作中用到了在ASP.NET MVC中以post方式传递数组参数的情况,记录下来,以供参考. 一.准备参数对象 在本例中,我会传递两个数组参数:一个字符串数组,一个自定义对象数组.这个自定义对象 ...
- SharePoint _layouts下自定义程序页面权限管理
在sharepoint中,_layouts下的自定义页面没有特别的权限,只要用户能访问sharepoint站点就可以访问_layouts下的自定义程序页面,现在我们需要给自定义页面做一下权限认证.要求 ...
- 一个简易的WebServer程序
现在这个公司的it管理真不知道说什么了,我主要从事.net方向的开发,公司电脑配置还是win7了,可是自己没有安装iis的权限,it也拒绝安装,想玩玩web安全都不行.于是乎决定开发一个window ...
- SQL SERVER CXPACKET-Parallelism Wait Type 的惯用解决方案
最近我的两个库出现,出现较多的CXPACKET等待,在网上找了一下资料.其中有篇一个SQL Server专栏作家的文章不错,也解决了我的一些疑问,就翻译在这里. 翻译整理仅用于传播资讯之目的. 原文出 ...
- Android实现录音的方法(最重要的是对MediaRecorder的试用方法)
package cn.eoe.record; import java.io.File; import java.io.IOException; import android.app.Activity; ...
- Java Web 生成临时文件并下载(原)
概述:本文是 java 服务器端生成文件并下载的示例,并不完善,下载之后一般来说还需要删除临时文件. 注意:临时文件存放在 /WEB-INF/tmp 目录下,所以先要把 tmp 目录建起来. pu ...
- 主机无法访问虚拟机的apache解决办法
1.前言 今天学习搭建wordpress,apache服务器安装在虚拟机的Centos上.配置好以后,发现在虚拟机上可以访问,但在windows主机上不能访问.于是百度.google一下,终于解决问题 ...
- Docker worker nodes shown as “Down” after re-start
After docker is shutdown, the worker node changes its status to Down, but availability remains at A ...
- 程序员的福音,AI可以自动修复bug了!
人工智能完全学会自己编程,可能说起来还有一种科幻感,但 AI 帮程序员找 bug 这件事,已经达到了不错的水平. 北京大学.微软亚洲研究院和中国电子科技大学就一起尝试着让 AI 找 bug.微软亚洲研 ...