/*********************************************************************************
|
* Copyright: (C) 2025 LingYun IoT System Studio
|
* All rights reserved.
|
*
|
* Filename: epoll.c
|
* Description: This file is epoll example.
|
*
|
* Version: 1.0.0(11/06/2025)
|
* Author: Guo Wenxue <guowenxue@gmail.com>
|
* ChangeLog: 1, Release initial version on "11/06/2025 10:33:45 AM"
|
*
|
********************************************************************************/
|
#include <stdio.h>
|
#include <string.h>
|
#include <unistd.h>
|
#include <errno.h>
|
#include <sys/epoll.h>
|
#include <sys/socket.h>
|
#include <netinet/in.h>
|
|
#define MAX_EVENTS 2 /* 监听 STDIN + sockfd */
|
|
int main(void)
|
{
|
int sockfd;
|
struct sockaddr_in addr;
|
int nfds;
|
int reuse = 1;
|
|
int epfd;
|
struct epoll_event ev, events[MAX_EVENTS];
|
|
sockfd = socket(AF_INET, SOCK_STREAM, 0); /* 创建套接字 */
|
|
addr.sin_family = AF_INET;
|
addr.sin_port = htons(8888);
|
addr.sin_addr.s_addr = INADDR_ANY;
|
|
setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse));
|
bind(sockfd, (struct sockaddr *)&addr, sizeof(addr));
|
listen(sockfd, 5);
|
|
/* 创建 epoll 实例 */
|
epfd = epoll_create1(0);
|
if (epfd < 0)
|
{
|
printf("epoll_create1 failure: %s\n", strerror(errno));
|
return 1;
|
}
|
|
/* 将 STDIN(键盘) 添加到 epoll 监控列表 */
|
ev.events = EPOLLIN;
|
ev.data.fd = STDIN_FILENO;
|
if (epoll_ctl(epfd, EPOLL_CTL_ADD, STDIN_FILENO, &ev) < 0)
|
{
|
printf("epoll_ctl add stdin failure: %s\n", strerror(errno));
|
return 2;
|
}
|
|
/* 将 socket 添加到 epoll 监控列表 */
|
ev.events = EPOLLIN;
|
ev.data.fd = sockfd;
|
if (epoll_ctl(epfd, EPOLL_CTL_ADD, sockfd, &ev) < 0)
|
{
|
printf("epoll_ctl add sockfd failure: %s\n", strerror(errno));
|
return 2;
|
}
|
|
printf("epoll() monitor socket[8888] and stdin now...\n");
|
|
while (1)
|
{
|
/* 调用 epoll 等待事件发生 */
|
nfds = epoll_wait(epfd, events, MAX_EVENTS, 10000);
|
if (nfds == -1)
|
{
|
printf("epoll error: %s\n", strerror(errno));
|
break;
|
}
|
else if (nfds == 0)
|
{
|
printf("timeout...\n");
|
continue;
|
}
|
|
/* 程序走到这里说明nfds>0,即监听的文件描述符中有事件发生了. */
|
|
/* 有多少个文件描述符发生了事件就处理多少个 */
|
for (int i = 0; i < nfds; i++)
|
{
|
int fd = events[i].data.fd;
|
|
if (fd == STDIN_FILENO)
|
{
|
char buf[128];
|
ssize_t n = read(STDIN_FILENO, buf, sizeof(buf) - 1);
|
if (n > 0)
|
{
|
buf[n] = '\0';
|
printf("You typed in keyboard: %s\n", buf);
|
}
|
}
|
else if (fd == sockfd)
|
{
|
int client = accept(sockfd, NULL, NULL);
|
if (client >= 0)
|
{
|
printf("Accept and close connection: %d\n", client);
|
close(client);
|
}
|
}
|
}
|
}
|
|
close(sockfd);
|
return 0;
|
}
|