服务器端

#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例子(一)的更多相关文章

  1. Libevent例子(二)

    服务端 #include<netinet/in.h> #include<stdio.h> #include<string.h> #include<event. ...

  2. libevent学习总结

    1. 信息隐藏:看*-internal.h文件 如bufferevent_private结构体在bufferevent_async.c中使用时: static inline struct buffer ...

  3. libevent源码分析:http-server例子

    http-server例子是libevent提供的一个简单web服务器,实现了对静态网页的处理功能. /* * gcc -g -o http-server http-server.c -levent ...

  4. libevent源码分析:hello-world例子

    hello-world是libevent自带的一个例子,这个例子的作用是启动后监听一个端口,对于所有通过这个端口连接上服务器的程序发送一段字符:hello-world,然后关闭连接. /* * gcc ...

  5. libevent源码分析:signal-test例子

    signal-test是libevent自带的一个例子,展示了libevent对于信号事件的处理方法. #include <sys/types.h> #include <event2 ...

  6. libevent源码分析:time-test例子

    time-test例子是libevent自带的一个例子,通过libevent提供的定时事件来实现,间隔固定时间打印的功能. /* * gcc -g -o time-test time-test.c - ...

  7. [z]Libevent使用例子,从简单到复杂

    [z]http://blog.csdn.net/luotuo44/article/details/39670221 本文从简单到复杂,展示如何使用libevent.网上的许多例子都是只有服务器端的,本 ...

  8. Libevent学习笔记(五) 根据例子学习bufferevent

    libevent中提供了一个Hello-world.c 的例子,从这个例子可以学习libevent是如何使用bufferevent的. 这个例子在Sample中 这个例子之前讲解过,这次主要看下buf ...

  9. 【Networking】Libevent客户端例子

    [原]Libevent客户端例子 时间 -- :: luotuo44的专栏 原文 http://blog.csdn.net/luotuo44/article/details/34416429 主题 l ...

随机推荐

  1. HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\aspnet_state\Parameters\AllowRemoteConnection

    ylbtech-Error-WebForm: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\aspnet_state\Parameters\ ...

  2. go语言之进阶篇WriteString的使用

    1.WriteString的使用 示例: package main import ( "fmt" "os" ) func WriteFile(path stri ...

  3. 8 个基于 Lucene 的开源搜索引擎推荐

    Lucene是一种功能强大且被广泛使用的搜索引擎,以下列出了8种基于Lucene的搜索引擎,你可以想象它们有多么强大. 1. Apache Solr Solr 是一个高性能,采用Java5开发,基于L ...

  4. ubuntu服务器常见使用技巧及-kill掉后GPU显存不释放进程-

    如何解决python进程被kill掉后GPU显存不释放的问题 1 重新开一个shell,然后输入: ps aux|grep user_name|grep python.所有该用户下的python程序就 ...

  5. 极光推送 JPush 简介 集成 MD

    Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...

  6. Android教你怎样一步步打造通用适配器

    前言 在Android开发中ListView是最为经常使用的控件之中的一个,基本每一个应用都会涉及到它,要使用ListView列表展示,就不可避免地涉及到另外一个东西--Adapter,我们都知道,A ...

  7. springMVC 防重校验(拦截器)

    <mvc:interceptor> <mvc:mapping path="/**"/> <bean class="com.bitspace. ...

  8. 给ajax表单提交数据前面加上实体名称

    有时候我们后台做了一个引用类型例如: 下面的实体以C#为例 public class Order{ public string orderId{get;set;} public OrderItem o ...

  9. .NET 基于任务的异步模式(Task-based Asynchronous Pattern,TAP) async await

    本文内容 概述 编写异步方法 异步程序中的控制流 API 异步方法 线程 异步和等待 返回类型和参数 参考资料 下载 Demo 下载 Demo TPL 与 APM 和 EAP 结合(APM 和 EAP ...

  10. Spring+hibernate+struts错题集

    1.严重: Exception starting filter struts2 java.lang.ClassNotFoundException: org.apache.struts2.dispatc ...