1.句柄(Handle) 在Windows下是句柄,在Linux下就是文件描述符
2.事件多路分发器(EventDemultiplexer) 通过IO函数实现的,就是IO函数
3.事件处理器和具体事件处理器 就是回调函数
4.编译的时候要加上-levent 5.当程序运行时,摁Ctrl+C就会触发一个信号,就会调用信号的回调函数,就会打印出^Csig=2,程序无法通过Ctrl+C退出,可以通过Ctrl+\来退出
信号和时间如果都是永久性事件EV_PERSIST,那么Ctrl+C就一直不终止程序而且每隔5秒会打印一个time out 如果信号和时间如果都不是永久性事件EV_PERSIST,那么Ctrl+C第一次会打印出^Csig=2,第二次Ctrl+C就会按照默认情况下将程序终止,时间只会打印出一个time out 6.当信号和时间都不是永久性事件EV_PERSIST的情况下,Ctrl+C再过5秒后打印出time out后,程序就会自动终止 7.IO事件多路分发器,也就是IO函数可以监测三个队列(读/写事件,计时器事件,信号时间)上哪个上面有事件就绪,它能检测的前提是三个队列上面都必须要有数据,就是有数据让我们去处理,如果三个队列都为空,程序就会自动退出,因为IO事件没有事情可以做了
哪个队列有事件产生,就会把事件放入到就绪队列中,它会帮我们调用就绪队列中的事件对应的回调函数,如果有永久事件,还会返回回去到对应的事件队列中 8.event_base_disopatch(base);函数返回的方式
答案:①三个事件队列都为空,读/写队列、计时器队列、信号队列 ②调用退出事件循环的方法event_base_loopexit();
9.服务器端代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <sys/time.h>
#include <event.h>
#include <assert.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/socket.h>
struct mess
{
struct event* c_ev;
};
int socket_init();
void recv_cb(int fd,short ev,void* arg)
{
struct mess* p = (struct mess*)arg;
if(ev & EV_READ)
{
char buff[128] = {0};
int n = recv(fd,buff,127,0);
if(n<=0)
{
event_free(p->c_ev);
free(p);
close(fd);
printf("close\n");
return ;
}
printf("recv(%d)=%s\n",fd,buff);
send(fd,"ok",2,0);
}
}
void accept_cb(int fd,short ev,void* arg)
{
struct event_base* base = (struct event_base*)arg;
if(ev & EV_READ)
{
struct sockaddr_in caddr;
int len = sizeof(caddr);
int c = accept(fd,(struct sockaddr*)&caddr,&len);
if(c<0)
{
return ;
}
printf("accpet c=%d\n",c);
struct mess *p = (struct mess*)malloc(sizeof(struct mess));
if(p == NULL)
{
close(c);
return ;
}
p->c_ev = event_new(base,c,EV_READ|EV_PERSIST,recv_cb,p);
if(p->c_ev == NULL)
{
close(c);
return ;
}
event_add(p->c_ev,NULL);
}
}
int main()
{
int sockfd = socket_init();
assert(sockfd != -1);
struct event_base* base = event_init();
assert(base != NULL);
struct event * sock_ev = event_new(base,sockfd,EV_READ|EV_PERSIST,accept_cb,base);
assert(sock_ev != NULL);
event_add(sock_ev,NULL);
event_base_dispatch(base);
event_free(sock_ev);
event_base_free(base);
close(sockfd);
exit(0);
}
int socket_init()
{
int sockfd = socket(AF_INET,SOCK_STREAM,0);
if(sockfd == -1)
{
return -1;
}
struct sockaddr_in saddr;
memset(&saddr,0,sizeof(saddr));
saddr.sin_family = AF_INET;
saddr.sin_port = htons(6000);
saddr.sin_addr.s_addr = inet_addr("127.0.0.1");
int res = bind(sockfd,(struct sockaddr*)&saddr,sizeof(saddr));
if(res == -1)
{
return -1;
}
res = listen(sockfd,5);
if(res == -1)
{
return -1;
}
return sockfd;
}
10.客户端代码
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <assert.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
int main()
{
int sockfd = socket(AF_INET,SOCK_STREAM,0);
assert(sockfd != -1);
struct sockaddr_in saddr;
memset(&saddr,0,sizeof(saddr));
saddr.sin_family = AF_INET;
saddr.sin_port = htons(6000);
saddr.sin_addr.s_addr = inet_addr("127.0.0.1");
int res = connect(sockfd,(struct sockaddr*)&saddr,sizeof(saddr));
assert(res != -1);
while(1)
{
char buff[128] = {0};
printf("input\n");
fgets(buff,128,stdin);
if(strncmp(buff,"end",3) == 0)
{
break;
}
send(sockfd,buff,strlen(buff)-1,0);
memset(buff,0,128);
recv(sockfd,buff,127,0);
printf("buff=%s\n",buff);
}
close(sockfd);
}
|