/********************************************************************************* * Copyright: (C) 2025 LingYun IoT System Studio * All rights reserved. * * Filename: socketd_epoll.c * Description: This file is TCP socket server(epoll) example program. * * Version: 1.0.0(10/20/2025) * Author: Guo Wenxue * ChangeLog: 1, Release initial version on "10/20/2025 09:48:51 PM" * ********************************************************************************/ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define BACKLOG 13 #define MAX_EVENTS 4096 #define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0])) int g_stop = 0; /* program stop or not */ void sig_handler(int signum); int socket_init(int port); void print_usage(char *progname) { printf("%s usage: \n", progname); printf(" -p(--port): sepcify listen port.\n"); printf(" -h(--Help): print this help information.\n"); return ; } int main(int argc, char **argv) { int i, j; int rv = -1; int listen_fd, client_fd = -1; int port = 10086; int debug = 0; struct sockaddr_in cli_addr; socklen_t addr_len = sizeof(cli_addr); char buf[1024]; int fd; int epfd; int nfds = 0; struct epoll_event ev, events[MAX_EVENTS]; int ch; struct option opts[] = { {"debug", no_argument, NULL, 'd'}, {"port", required_argument, NULL, 'p'}, {"help", no_argument, NULL, 'h'}, {NULL, 0, NULL, 0} }; /* 解析命令行参数 */ while( (ch=getopt_long(argc, argv, "dp:h", opts, NULL)) != -1 ) { switch(ch) { case 'd': debug = 1; break; case 'p': port=atoi(optarg); break; case 'h': print_usage(argv[0]); return 0; } } /* 如果不是debug调试运行,就放到后台去运行 */ if( !debug ) daemon(0, 0); /* 安装信号 */ signal(SIGTERM, sig_handler); /* capture kill/killall signal */ signal(SIGINT, sig_handler); /* capture Ctrl+C signal */ signal(SIGSEGV, sig_handler); /* capture segmentation fault signal */ signal(SIGPIPE, sig_handler); /* capture socket error signal */ /* 创建监听套接字 */ if( (listen_fd = socket_init(port)) < 0 ) return 2; /* 创建 epoll 实例 */ epfd = epoll_create1(0); if (epfd < 0) { printf("epoll_create1 failure: %s\n", strerror(errno)); return 1; } /* 注册监听 socket 到 epoll 实例 */ ev.events = EPOLLIN; ev.data.fd = listen_fd; if (epoll_ctl(epfd, EPOLL_CTL_ADD, listen_fd, &ev) < 0) { printf("epoll_ctrl add listen_fd failure: %s\n", strerror(errno)); return -1; } while( !g_stop ) { /* epoll 一直阻塞等待, 永不超时 */ nfds = epoll_wait(epfd, events, MAX_EVENTS, -1); if( nfds <= 0 ) { /* poll()超时或有异常发生(如有信号到来),继续下次循环 */ printf("poll failure: %s\n", strerror(errno)); continue; } /* 程序走到这里说明 rv>0, 有文件描述符发生事件了 */ /* 逐个处理就绪事件 */ for(i=0; i