写点什么

写一个 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服务器开发/后台架构师免费学习地址

用户头像

还未添加个人签名 2020-11-26 加入

C/C++linux服务器开发群 812855908

评论

发布
暂无评论
写一个epoll的服务端程序_事件驱动_linux大本营_InfoQ写作社区