/********************************************************************************* * Copyright: (C) 2025 LingYun IoT System Studio * All rights reserved. * * Filename: socketd_poll.c * Description: This file is TCP socket server(poll) 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_FDS 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]; struct pollfd fds_array[MAX_FDS]; int need_update; int nfds = 0; int found; 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; /* 初始化 pollfd 数组 */ for (i=0; i0 && i>= nfds ) nfds = i+1; } need_update = 0; /* 清除更新标志 */ } /* poll 一直阻塞等待, 永不超时 */ rv=poll(fds_array, nfds, -1); if( rv <= 0 ) { /* poll()超时或有异常发生(如有信号到来),继续下次循环 */ printf("poll failure: %s\n", strerror(errno)); continue; } /* 程序走到这里说明 rv>0, 有文件描述符发生事件了 */ /* 检查是不是 listen_fd 发生了事件,如果有说明有新的客户端连接请求到来 */ if (fds_array[0].revents & POLLIN) { /* 接收新的客户端连接请求 */ client_fd = accept(listen_fd, (struct sockaddr*)&cli_addr, &addr_len); if(client_fd < 0) { printf("accept new socket failure: %s\n", strerror(errno)); continue; } printf("Accept new client[%s:%d] with fd [%d]\n", inet_ntoa(cli_addr.sin_addr), ntohs(cli_addr.sin_port), client_fd); /* 从符数组中找一个空位置,将新的客户端文件描述符加进去 */ found = 0; for(i=0; i