写一个 epoll 的服务端程序
作者:linux大本营
- 2023-04-24 湖南
本文字数:1659 字
阅读完需:约 5 分钟
首先,epoll 是一种事件驱动的 I/O 模型,它可以用来处理多个客户端连接。下面是一个简单的 epoll 服务端程序:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/epoll.h>
#include <fcntl.h>
#define BUF_SIZE 4
#define EPOLL_SIZE 50
int setNonBlockingMode(int fd) {
int flag = fcntl(fd, F_GETFL, 0);
fcntl(fd, F_SETFL, flag | O_NONBLOCK);
return 0;
}
void errorHandling(const char *message) {
fputs(message, stderr);
fputc('\n', stderr);
exit(1);
}
int main(int argc, char *argv[]) {
int servSock, clntSock;
struct sockaddr_in servAddr, clntAddr;
socklen_t clntAddrSize;
char buf[BUF_SIZE];
struct epoll_event *epEvents;
struct epoll_event event;
int epfd, eventCnt, i;
if (argc != 2)
errorHandling("Usage: ./server <port>");
servSock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
if (servSock == -1)
errorHandling("socket() error");
memset(&servAddr, 0, sizeof(servAddr));
servAddr.sin_family = AF_INET;
servAddr.sin_addr.s_addr = htonl(INADDR_ANY);
servAddr.sin_port = htons(atoi(argv[1]));
if (bind(servSock, (struct sockaddr *) &servAddr, sizeof(servAddr)) == -1)
errorHandling("bind() error");
if (listen(servSock, 5) == -1)
errorHandling("listen() error");
epfd = epoll_create(EPOLL_SIZE);
epEvents = malloc(sizeof(struct epoll_event) * EPOLL_SIZE);
event.events = EPOLLIN;
event.data.fd = servSock;
epoll_ctl(epfd, EPOLL_CTL_ADD, servSock, &event);
while (1) {
eventCnt = epoll_wait(epfd, epEvents, EPOLL_SIZE, -1);
if (eventCnt == -1)
errorHandling("epoll() error");
for (i = 0; i < eventCnt; ++i) {
if (epEvents[i].data.fd == servSock) {
clntAddrSize = sizeof(clntAddr);
clntSock = accept(servSock, (struct sockaddr *) &clntAddr, &clntAddrSize);
setNonBlockingMode(clntSock);
event.events = EPOLLIN | EPOLLET;
event.data.fd = clntSock;
epoll_ctl(epfd, EPOLL_CTL_ADD, clntSock, &event);
printf("Connected client: %d\n", clntSock);
} else {
while (1) {
int strLen = read(epEvents[i].data.fd, buf, BUF_SIZE);
if (strLen == 0) {
epoll_ctl(epfd, EPOLL_CTL_DEL, epEvents[i].data.fd, NULL);
close(epEvents[i].data.fd);
printf("Closed client: %d\n", epEvents[i].data.fd);
break;
} else if (strLen < 0) {
if (errno == EAGAIN)
break;
errorHandling("read() error");
} else {
write(epEvents[i].data.fd, buf, strLen);
}
}
}
}
}
close(servSock);
close(epfd);
return 0;
}
复制代码
这个程序创建了一个在指定端口上监听的套接字,然后使用 epoll 机制来处理多个客户端连接。当客户端连接时,程序将文件描述符添加到 epoll 实例中。
然后,程序使用 epoll_wait()函数来等待任何事件发生,并使用 read()和 write()函数来处理客户端请求并向客户端发送响应。
相关技术视频教程:c/c++ linux服务器开发/后台架构师免费学习地址
划线
评论
复制
发布于: 刚刚阅读数: 3
linux大本营
关注
还未添加个人签名 2020-11-26 加入
C/C++linux服务器开发群 812855908
评论