libev+TCP服务器事件轮询实例demo
#include <stdio.h> #include <netinet/in.h> #include <arpa/inet.h> #include <stdlib.h> #include <stdint.h> #include <fcntl.h> #include <errno.h> #include <unistd.h> #include <ev.h> #define PORT 12100 #define BUFFER_SIZE 1024 #define MAX_LISTEN 5 /*初始化服务端*/ int server_socket_init(int *sd, char *ipaddr, uint16_t port) { //创建socket int sock = socket(AF_INET, SOCK_STREAM, 0); if (-1 == sock) goto err1; //设置立即释放端口并可以再次使用 int reuse = 1; if (-1 == setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse))) goto err2; //设置为非阻塞 if (-1 == fcntl(sock, F_SETFL, fcntl(sock, F_GETFL) | O_NONBLOCK)) goto err2; struct sockaddr_in addr; memset(&addr, 0 , sizeof(addr)); addr.sin_family = AF_INET; addr.sin_port = htons(port); if (NULL == ipaddr) { addr.sin_addr.s_addr = htonl(INADDR_ANY); } else { addr.sin_addr.s_addr = inet_addr(ipaddr); } //绑定监听 if (-1 == bind(sock, (struct sockaddr *)&addr, sizeof(addr))) goto err2; if (-1 == listen(sock, MAX_LISTEN)) goto err2; *sd = sock; return 0; err2: close(sock); err1: return -1; } /*读回调*/ void read_cb(struct ev_loop *loop, struct ev_io *watcher, int revents) { char buffer[BUFFER_SIZE] = {0}; if (EV_ERROR & revents) { printf("read got invalid event...\r\n"); return; } int res = 0; int32_t bytes = read(watcher->fd, buffer, sizeof(buffer)); if (-1 == bytes) { //tcp Error if (EINTR != errno && EAGAIN != errno) { res = 1; } } else if (0 == bytes) { //tcp Close res = 2; } if (0 != res) { //关闭事件循环并释放watcher printf("TCP CLOSE\r\n"); ev_io_stop(loop,watcher); free(watcher); } else { printf("READ:\r\n %s\r\n", buffer); } } /*accept回调函数*/ void accept_cb(struct ev_loop *loop, struct ev_io *watcher, int revents) { struct sockaddr_in client_addr; socklen_t client_len = sizeof(client_addr); if (EV_ERROR & revents) { printf("accept got invalid event...\r\n"); return; } //accept连接 int sock = accept(watcher->fd, (struct sockaddr *)&client_addr, &client_len); if (-1 == sock) { return; } //设置非阻塞 if(-1 == fcntl(sock, F_SETFL, fcntl(sock, F_GETFL) | O_NONBLOCK)) { close(sock); return; } printf("Successfully connected with client: %s:%u\r\n", \ inet_ntoa(client_addr.sin_addr), client_addr.sin_port); //加入事件循环 struct ev_io *w_client = (struct ev_io*) malloc (sizeof(struct ev_io)); ev_io_init(w_client, read_cb, sock, EV_READ); ev_io_start(loop, w_client); } int main() { int sd; struct ev_io w_accept; struct ev_loop *loop = ev_loop_new(EVBACKEND_EPOLL); if (NULL == loop) { printf("loop create failed\r\n"); return -1; } if (server_socket_init(&sd, NULL, PORT) < 0) { printf("server init failed\r\n"); return -1; } ev_io_init(&w_accept, accept_cb, sd, EV_READ); ev_io_start(loop, &w_accept); ev_run(loop, 0); return 0; } ———————————————— 版权声明:本文为CSDN博主「Dancer__Sky」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/Dancer__Sky/article/details/85159058