一个简单的服务器示例
1、event_base
使用libevent函数之前,需要分配一个event_base,它有一个事件集合,可以检测那些事件是激活的。
创建:struct event_base *event_base_new(void);
2、服务器端代码流程:
- 先创建socket套接字
m_listenfd = socket(AF_INET,SOCK_STREAM,NULL);
- 对服务器地址进行初始化
bzero(&m_serAddr,sizeof(m_serAddr));
m_serAddr.sin_family = AF_INET;
m_serAddr.sin_addr.s_addr = htonl(INADDR_ANY);
m_serAddr.sin_port = htons(8889);
- 绑定套接字地址,端口
bind(m_listenfd,(struct sockaddr*)&m_serAddr,sizeof(m_serAddr))
- listen
listen(m_listenfd,10)
- 初始化一个event_base
base = event_base_new();
- 将监听描述符设置为不阻塞
evutil_make_socket_nonblocking(m_listenfd);
- 新建事件,绑定监听描述符上的接收连接事件,并添加到事件循环
ev_listen = event_new(base,m_listenfd,EV_READ|EV_PERSIST,accept_cb,base);
//EV_PERSIST:使每次回调函数执行之后,事件仍然是pending
event_add(ev_listen,NULL); //no-pending à pending
- 开始事件循环
event_base_dispatch(base);
其中,设置的接收连接的回调函数中做了如下的事:
1)接收连接,获取新建连接的描述符
sockfd = accept(fd,(struct sockaddr*)&client, &len);
2)设置新建连接为非阻塞
evutil_make_socket_nonblocking(sockfd);
3)对新建连接描述符的read事件进行监听,设置对应的回调函数
struct event *ev = event_new(NULL,-1,0,NULL,NULL);
event_assign(ev,base,sockfd,EV_READ|EV_PERSIST, socket_read_cb, (void*)ev);
event_add(ev,NULL);
了解了libevent中事件的创建,添加,循环运行机制,详细代码可见git@github.com:coding-coder/LIbeventTest.git