赞
踩
#include <stdio.h>
#include <event2/event.h>
#include <event2/bufferevent.h>
#define SERVER_PORT 8080
#define BUFFER_MAX 1024
struct event* eventList[1024];
void write_cb(evutil_socket_t sock, short events, void *arg);
void read_cb(evutil_socket_t sock, short events, void *arg);
void event_cb(struct bufferevent *bev, short event, void *arg)
{
if(event & BEV_EVENT_EOF)
{
bufferevent_free(bev);
}
}
void read_cb(evutil_socket_t sock, short events, void *arg)
{
char buffer[BUFFER_MAX] = {0};
int count = recv(sock, buffer, BUFFER_MAX, 0);
if(count <= 0)
{
// 跳出循环
//event_base_loopbreak((struct event_base*)arg);
event_del(eventList[sock]);
close(sock);
}
else
{
// 修改为写事件
printf("%s\n", buffer);
event_del(eventList[sock]);
eventList[sock] = event_new((struct event_base *)arg, sock, EV_WRITE | EV_PERSIST, write_cb, (struct event_base *)arg);
event_add(eventList[sock], NULL);
}
}
void write_cb(evutil_socket_t sock, short events, void *arg)
{
char buffer[BUFFER_MAX] = {0};
sprintf(buffer, "%s", "hellp libevent");
int count = send(sock, buffer, strlen(buffer), 0);
if(count < 0)
{
}
else
{
// 修改为读事件
event_del(eventList[sock]);
eventList[sock] = event_new((struct event_base *)arg, sock, EV_READ | EV_PERSIST, read_cb, (struct event_base *)arg);
event_add(eventList[sock], NULL);
}
}
void accept_cb(evutil_socket_t sock, short events, void *arg)
{
// 添加一个新的事件
struct sockaddr_in clienAddr;
socklen_t len = sizeof(clienAddr);
int clifd = accept((int)sock, (struct sockaddr*)&clienAddr, &len);
if(clifd == -1)
{
perror("accept");
return;
}
//evutil_make_socket_nonblocking(clifd);
// 将监听fd加入到事件集合
eventList[clifd] = event_new((struct event_base *)arg, clifd, EV_READ | EV_PERSIST, read_cb, (struct event_base *)arg);
event_add(eventList[clifd], NULL);
}
int main()
{
evutil_socket_t fd = socket(AF_INET, SOCK_STREAM, 0);
if(fd == -1)
{
perror("socket");
exit(-1);
}
// 允许同个地址多次绑定(TIME_WAIT)
evutil_make_listen_socket_reuseable(fd);
// 设置套接字为非阻塞
evutil_make_socket_nonblocking(fd);
// 五元组
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = htonl(INADDR_ANY);
addr.sin_port = htons(SERVER_PORT);
// 绑定
if(-1 == bind(fd, (struct sockaddr*)&addr, (socklen_t)sizeof(addr)))
{
perror("bind");
exit(-1);
}
// listen
if(-1 == listen(fd, 10))
{
perror("listen");
exit(-1);
}
//------------------------ 事件管理 ---------------------------------//
/* 使用默认方式
+-------------------------------------------------------------------+
| [*] libevent在Linux默认会优先是用epoll
| [*] struct event_base* base = event_base_new();
+-------------------------------------------------------------------+
| [*] event_get_supported_methods查看所有所支持的方式 epoll、select..
const char **methods = event_get_supported_methods();
for(int i = 0; methods[i] != NULL; i++)
{
printf("methods[%d]:%s\n", i, methods[i]);
}
+-------------------------------------------------------------------+
*/
struct event_config* config = event_config_new();
event_config_avoid_method(config, "epoll");
struct event_base* base = event_base_new_with_config(config);
event_config_free(config);
// 将监听fd加入到事件集合
struct event* event_listen = event_new(base, fd, EV_READ | EV_PERSIST, accept_cb, base);
event_add(event_listen, NULL); // 不设置超时时间
event_base_dispatch(base);
event_base_free(base);
evutil_closesocket(fd);
return 0;
}
epoll
#include <stdio.h>
#include <sys/epoll.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <fcntl.h>
#include <arpa/inet.h>
#define SERVER_PORT 8080
#define MAX_EVENTS 1024
#define BUFFER_MAX 1024
static int epfd = 0;
void read_cb(int fd)
{
char buffer[BUFFER_MAX] = {0};
int count = recv(fd, buffer, BUFFER_MAX, 0);
if(count <= 0)
{
epoll_ctl(epfd, EPOLL_CTL_DEL, fd, NULL);
}
else
{
printf("%s\n", buffer);
struct epoll_event event;
event.data.fd = fd;
event.events = EPOLLOUT;
epoll_ctl(epfd, EPOLL_CTL_MOD, fd, &event);
}
}
void write_cb(int fd)
{
// 可写时就会触发 --> 是可写时,不是写时
char buffer[BUFFER_MAX] = {0};
sprintf(buffer, "%s", "Hello epoll");
int count = send(fd, buffer, strlen(buffer), 0);
if(count == 0)
{
printf("count 0\n");
}
struct epoll_event event;
event.data.fd = fd;
event.events = EPOLLIN;
epoll_ctl(epfd, EPOLL_CTL_MOD, fd, &event);
}
void accept_cb(int fd)
{
struct sockaddr_in clienAddr;
socklen_t len = sizeof(clienAddr);
int clifd = accept(fd, (struct sockaddr*)&clienAddr, &len);
if(clifd == -1)
{
perror("accept");
return;
}
// 将套接字(FD)设置成非阻塞
// int flags;
// flags = fcntl(clifd, F_GETFL, NULL);
// if(flags < 0)
// {
// perror("fcntl");
// return;
// }
// if(!(flags & O_NONBLOCK)) // 如果没有设置非阻塞
// {
// if(-1 == fcntl(clifd, F_SETFL, flags | O_NONBLOCK))
// {
// perror("fcntl");
// return;
// }
// }
// 加入到epoll中
struct epoll_event event_cli;
event_cli.data.fd = clifd;
event_cli.events = EPOLLIN;
if(-1 == epoll_ctl(epfd, EPOLL_CTL_ADD, clifd, &event_cli))
{
perror("epoll_ctl");
return;
}
}
int main()
{
int fd = -1;
do
{
int fd = socket(AF_INET, SOCK_STREAM, 0);
if(fd == -1)
{
perror("socket");
break;
}
// 允许同个地址多次绑定(TIME_WAIT)
int optval = 1;
setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (void*)&optval, (socklen_t)sizeof(optval));
// 将套接字(FD)设置成非阻塞
int flags;
flags = fcntl(fd, F_GETFL, NULL);
if(flags < 0)
{
perror("fcntl");
break;
}
if(!(flags & O_NONBLOCK)) // 如果没有设置非阻塞
{
if(-1 == fcntl(fd, F_SETFL, flags | O_NONBLOCK))
{
perror("fcntl");
break;
}
}
// 五元组
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = htonl(INADDR_ANY);
addr.sin_port = htons(SERVER_PORT);
// 绑定
if(-1 == bind(fd, (struct sockaddr*)&addr, (socklen_t)sizeof(addr)))
{
perror("bind");
break;
}
// listen
if(-1 == listen(fd, 10))
{
perror("listen");
break;
}
//------------------------ 事件管理 ---------------------------------//
epfd = epoll_create(10);
if(-1 == epfd)
{
perror("epoll_create");
break;
}
// 将监听fd加入到事件集合
struct epoll_event event_listen;
event_listen.data.fd = fd;
event_listen.events = EPOLLIN;
if(-1 == epoll_ctl(epfd, EPOLL_CTL_ADD, fd, &event_listen))
{
perror("epoll_ctl");
break;
}
struct epoll_event events[MAX_EVENTS];
while(1)
{
int readyno = epoll_wait(epfd, events, MAX_EVENTS, -1);
if(-1 == readyno)
{
perror("epoll_wait");
break;
}
for(int i = 0; i < readyno; ++i)
{
int fd_event = events[i].data.fd;
if(events[i].events & EPOLLIN)
{
if(fd_event == fd)
{
accept_cb(fd_event);
}
else
{
read_cb(fd_event);
}
}
else if(events[i].events & EPOLLOUT)
{
write_cb(fd_event);
}
}
}
}while (0);
if(fd != -1)
{
close(fd);
}
if(epfd != 0)
{
close(epfd);
}
return 0;
}
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。