路径:libevent-2.1.8-stable/sample
文件 event-read-fifo.c
这个案例实现的是从命名管道读取内容。(考虑在Linux环境,删除跨平台相关代码)
#include <event2/event-config.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/queue.h>
#include <unistd.h>
#include <sys/time.h>
#include <signal.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <event2/event.h>
static void
fifo_read(evutil_socket_t fd, short event, void *arg)
{
char buf[255];
int len;
struct event *ev = arg;
fprintf(stderr, "fifo_read called with fd: %d, event: %d, arg: %p\n",
(int)fd, event, arg);
len = read(fd, buf, sizeof(buf) - 1);
if (len <= 0) {
if (len == -1)
perror("read");
else if (len == 0)
fprintf(stderr, "Connection closed\n");
event_del(ev);
event_base_loopbreak(event_get_base(ev));
return;
}
buf[len] = '\0';
fprintf(stdout, "Read: %s\n", buf);
}
/* On Unix, cleanup event.fifo if SIGINT is received. */
static void
signal_cb(evutil_socket_t fd, short event, void *arg)
{
struct event_base *base = arg;
event_base_loopbreak(base);
}
int
main(int argc, char **argv)
{
struct event *evfifo;
struct event_base* base;
struct event *signal_int;
struct stat st;
const char *fifo = "event.fifo";
int socket;
if (lstat(fifo, &st) == 0) {
if ((st.st_mode & S_IFMT) == S_IFREG) {
errno = EEXIST;
perror("lstat");
exit(1);
}
}
unlink(fifo);
if (mkfifo(fifo, 0600) == -1) {
perror("mkfifo");
exit(1);
}
socket = open(fifo, O_RDONLY | O_NONBLOCK, 0);
if (socket == -1) {
perror("open");
exit(1);
}
fprintf(stderr, "Write data to %s\n", fifo);
fprintf(stderr, "Write data to %s %d\n", fifo, socket);
/* Initalize the event library */
base = event_base_new();
/* Initalize one event */
/* catch SIGINT so that event.fifo can be cleaned up */
signal_int = evsignal_new(base, SIGINT, signal_cb, base);
event_add(signal_int, NULL);
evfifo = event_new(base, socket, EV_READ|EV_PERSIST, fifo_read,
event_self_cbarg());
/* Add it to the active events, without a timeout */
event_add(evfifo, NULL);
event_base_dispatch(base);
event_base_free(base);
close(socket);
unlink(fifo);
libevent_global_shutdown();
return (0);
}
编译:
gcc event-read-fifo.c -levent -o eventreadfifo
运行。
然后写一个客户端往同一个命名管道写数据:
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <limits.h>
#include <stdlib.h>
#include <time.h>
#define BUFS PIPE_BUF
int main()
{
int fd;
int n, i;
char buf[BUFS];
time_t tp;
printf("I am %d\n", getpid());
if (access("event.fifo", F_OK) != 0)
{
if (mkfifo("event.fifo", 0666))
{
printf("event.fifo not existed, and create event.fifo failed!\n");
exit(1);
}
}
if ((fd = open("event.fifo", O_WRONLY)) < 0)
{
printf("Open failed!\n");
exit(1);
}
for (i = 0; i < 10; i++)
{
time(&tp);
n = sprintf(buf, "write_fifo %d sends %s", getpid(), ctime(&tp));
printf("Send msg:%s", buf);
if ((write(fd, buf, n + 1)) < 0)
{
printf("Write failed!\n");
close(fd);
exit(1);
}
sleep(1);
}
close(fd);
exit(0);
}
编译:
gcc fifowrite.c -levent -o fifowrite
客户端输出,最后用ctrl + c 退出:
I am 5339
Send msg:write_fifo 5339 sends Thu Jan 10 09:38:41 2019
Send msg:write_fifo 5339 sends Thu Jan 10 09:38:42 2019
……
Send msg:write_fifo 5339 sends Thu Jan 10 09:38:47 2019
Send msg:write_fifo 5339 sends Thu Jan 10 09:38:48 2019
^C
服务端输出:
Write data to event.fifo
Write data to event.fifo 3
fifo_read called with fd: 3, event: 2, arg: 0x13b4870
Read: write_fifo 5339 sends Thu Jan 10 09:38:41 2019
……
fifo_read called with fd: 3, event: 2, arg: 0x13b4870
Read: write_fifo 5339 sends Thu Jan 10 09:38:48 2019
fifo_read called with fd: 3, event: 2, arg: 0x13b4870
Connection closed
结构体:
- event_base:保存事件(分发)循环的信息和状态
- event:单个事件
函数:
- event_del:从监听事件集中移除,若没有监听的事件,事件循环会退出
- event_base_loopbreak :退出事件循环
- event_base_new:新建一个event_base
- evsignal_new:新建一个event
- event_new:新建一个event
- event_add:将event 添加到监听的事件集
- event_base_dispatch:开启事件循环
- event_base_free:释放event_base
- libevent_global_shutdown:释放所有全局资源
- event_self_cbarg:返回event 自身作为参数,一般作为回调函数的参数
参考: