注册服务端接收事件
#include <cerrno>
#include <cstdio>
#include <cstring>
#include <event2/event.h>
#include <event2/util.h>
#include <iostream>
#include <netinet/in.h>
#include <sys/socket.h>
#ifdef _WIN32
#else
#include <signal.h>
#endif
void ListenCallback(evutil_socket_t sock, short what, void * arg) {
std::cout << "accept new connection!" << std::endl;
if (!(what & EV_READ)) {
std::cout << "Not Read" << std::endl;
return;
}
sockaddr_in sin;
memset(&sin, 0, sizeof(sin));
socklen_t size = sizeof(sin);
evutil_socket_t client_socket = accept(sock, (sockaddr*)&sin, &size);
if (client_socket <= 0) {
std::cerr << "accept error" << strerror(errno) << std::endl;
return;
}
char ip[16] = {0};
evutil_inet_ntop(AF_INET, &sin.sin_addr, ip, sizeof(ip));
std::cout << "accept new connection from " << ip << std::endl;
}
int main(int argc, char* argv[]) {
// 端口地址
int server_port = 8080;
if (argc > 1) {
// 从命令行传入指定的端口号
server_port = atoi(argv[1]);
}
#ifdef _WIN32
WSADATA wsa;
WSAStartup(MAKEWORD(2, 2), &wsa);
#else
// 使用断开连接socket,会发出此信号,造成程序退出,因此忽略此信号
if (signal(SIGPIPE, SIG_IGN) == SIG_ERR) {
return 1;
}
#endif
std::cout << "test event server!\n";
// 创建libevent的上下文,默认是创建base锁
event_base * base = event_base_new();
if (base) {
std::cout << "event_base_new success!" << std::endl;
}
// 创建socket,绑定端口
evutil_socket_t sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock <= 0) {
std::cerr << "socket error" << strerror(errno) << std::endl;
return -1;
}
// 设置地址复用和非阻塞
evutil_make_socket_nonblocking(sock);
evutil_make_listen_socket_reuseable(sock);
// 绑定端口
sockaddr_in sin;
memset(&sin, 0, sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_port = htons(server_port);
int re = ::bind(sock, (sockaddr*)&sin, sizeof(sin));
if (re != 0) {
std::cerr << "bind port error" << strerror(errno) << std::endl;
return -1;
}
std::cout << "bind port success!" << std::endl;
// 监听端口
listen(sock, 10);
// 创建监听事件
// EV_PERSIST持久化,不然只进入一次事件
// event_self_cbarg() 传递当前创建的event对象
event* ev = event_new(base, sock, EV_READ | EV_PERSIST | EV_ET , ListenCallback, event_self_cbarg());
// 开始监听事件
// 0表示超时事件
event_add(ev, 0);
// 事件循环
// 判断事件是否发生,分发事件到回调函数
event_base_dispatch(base);
// 关闭socket
evutil_closesocket(sock);
// 清除事件
event_del(ev);
event_free(ev);
// 释放libevent的上下文
event_base_free(base);
return 0;
}
编译
Makefile文件
test_event_server:first_libevent.cpp
g++ $^ -o $@ -levent
clean:
rm -f test_event_server
rm -f *.o
make test_event_server