Note
利用Libevent创建监听集合,将管道的读端与事件绑定并放入监听集合中,在管道另一端写内容,监听集合一旦监听到就会自动触发读取管道内内容
管道服务端
注意:编译的时候要加libevent库, gcc 管道服务端.c -o 管道服务端 -levent
// ##############################################################################################
//初始化事件(把fd和事件ev绑定) 参数:关联的文件描述符 事件类型 回调函数 回调函数参数
/*******函数原型 BEGIN********
struct event_base *event_init(void);
void
event_set(struct event *ev, evutil_socket_t fd, short events, void (*callback)(evutil_socket_t, short, void *), void *arg)
参数说明:
** this flag to event_for new()/event_assign() to get a timeout.
//#define EV_TIMEOUT 0x01
** Wait for a socket or FD to become readable
//#define EV_READ 0x02
** Wait for a socket or FD to become writeable
//#define EV_WRITE 0x04
** Wait for a POSIX signal to be raised
//#define EV_SIGNAL 0x08
**
* Persistent event: won't get removed automatically when activated.
*
* When a persistent event with a timeout becomes activated, its timeout
* is reset to 0.
**
#define EV_PERSIST 0x10
** Select edge-triggered behavior, if supported by the backend. **
#define EV_ET 0x20
**
* If this option is provided, then event_del() will not block in one thread
* while waiting for the event callback to complete in another thread.
*
* To use this option safely, you may need to use event_finalize() or
* event_free_finalize() in order to safely tear down an event in a
* multithreaded application. See those functions for more information.
**
#define EV_FINALIZE 0x40
**
* Detects connection close events. You can use this to detect when a
* connection has been closed, without having to read all the pending data
* from a connection.
*
* Not all backends support EV_CLOSED. To detect or require it, use the
* feature flag EV_FEATURE_EARLY_CLOSE.
**
#define EV_CLOSED 0x80
********函数原型 END*********/
// ##############################################################################################
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include <event.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
/********回调函数 BEGIN ******
原型:void (*callback)(evutil_socket_t, short, void *)
*********回调函数 END ********/
void fifo_read(evutil_socket_t fd, short events, void *arg)
{
char buf[32] = {0};
int ret = read(fd, buf, sizeof(buf));
if(-1 == ret)
{
perror("read err");
exit(1);
}
printf("从管道内读取 %s\n", buf);
}
int main()
{
int ret = mkfifo("fifo.temp",00700); //创建管道,成功返回1失败返回0;参数1管道文件,参数2权限
if(-1 == ret)
{
perror("mkfifo");
exit(1);
}
int fd = open("fifo.temp", O_RDONLY); //打开管道,设置只读取
if(-1 == fd)
{
perror("open err");
exit(1);
}
/********** 1、把管道fd与事件绑定 2、将事件加入到事件集合 3、**********/
//创建事件
struct event ev;
//初始化事件集合
event_init();
event_set(&ev, fd, EV_READ|EV_PERSIST, fifo_read, NULL); //EV_PERSIST 设置即使集合中没有事件监听,也不会退出
//把事件添加到集合中
event_add(&ev, NULL);
//开启监听,死循环, 如果集合中没有事件监听则返回
event_dispatch();
return 0;
}
管道客户端
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>
int main()
{
//创建有名管道
//int ret = mkfifo("fifo.temp", 00400 | 00200);
//if(-1 == ret)
//{
// perror("mkfifo err");
// exit(1);
//}
//默认是阻塞的
int fd = open("fifo.temp", O_WRONLY);
if(-1 == fd)
{
perror("open err");
exit(1);
}
int ret;
char buf[32] = {0};
while(1)
{
scanf("%s" ,buf);
ret = write(fd, buf, strlen(buf));
if(-1 == ret)
{
perror("write");
exit(1);
}
if(!strcmp(buf, "bye"))
{
break;
}
memset(buf, 0, sizeof(buf));
}
}


