给我写个epoll代码
时间: 2023-12-20 17:23:15 浏览: 43
好的,下面是一个简单的 epoll 服务器代码,可以监听端口并接收客户端的连接和数据:
```c++
#include <iostream>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/epoll.h>
#include <cstring>
#include <cstdlib>
#define MAX_EVENTS 512
#define BUF_SIZE 1024
int set_nonblocking(int fd) {
int flags = fcntl(fd, F_GETFL, 0);
if (flags == -1) {
return -1;
}
flags |= O_NONBLOCK;
return fcntl(fd, F_SETFL, flags);
}
int main() {
int listen_fd = socket(AF_INET, SOCK_STREAM, 0);
if (listen_fd < 0) {
std::cerr << "create socket error!" << std::endl;
exit(-1);
}
int reuse = 1;
setsockopt(listen_fd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse));
struct sockaddr_in server_addr{};
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
server_addr.sin_port = htons(8888);
if (bind(listen_fd, (struct sockaddr*) &server_addr, sizeof(server_addr)) < 0) {
std::cerr << "bind error!" << std::endl;
exit(-1);
}
if (listen(listen_fd, 5) < 0) {
std::cerr << "listen error!" << std::endl;
exit(-1);
}
int epoll_fd = epoll_create1(0);
if (epoll_fd < 0) {
std::cerr << "create epoll error!" << std::endl;
exit(-1);
}
struct epoll_event event{}, events[MAX_EVENTS];
event.data.fd = listen_fd;
event.events = EPOLLIN | EPOLLET;
epoll_ctl(epoll_fd, EPOLL_CTL_ADD, listen_fd, &event);
while (true) {
int num_events = epoll_wait(epoll_fd, events, MAX_EVENTS, -1);
for (int i = 0; i < num_events; ++i) {
if (events[i].data.fd == listen_fd) {
// accept new connection
struct sockaddr_in client_addr{};
socklen_t client_addr_len = sizeof(client_addr);
int client_fd = accept(listen_fd, (struct sockaddr*) &client_addr, &client_addr_len);
if (client_fd < 0) {
std::cerr << "accept error!" << std::endl;
continue;
}
std::cout << "accept new connection from "
<< inet_ntoa(client_addr.sin_addr)
<< ":" << ntohs(client_addr.sin_port)
<< std::endl;
set_nonblocking(client_fd);
event.data.fd = client_fd;
event.events = EPOLLIN | EPOLLET;
epoll_ctl(epoll_fd, EPOLL_CTL_ADD, client_fd, &event);
} else {
// receive data from client
int fd = events[i].data.fd;
char buf[BUF_SIZE];
int n = read(fd, buf, BUF_SIZE);
if (n < 0) {
if (errno == ECONNRESET) {
// client closed connection
epoll_ctl(epoll_fd, EPOLL_CTL_DEL, fd, &event);
close(fd);
std::cout << "client closed connection!" << std::endl;
} else {
std::cerr << "read error!" << std::endl;
}
} else if (n == 0) {
// client closed connection
epoll_ctl(epoll_fd, EPOLL_CTL_DEL, fd, &event);
close(fd);
std::cout << "client closed connection!" << std::endl;
} else {
std::cout << "received data from client: " << buf << std::endl;
// send data back to client
write(fd, buf, n);
}
}
}
}
close(listen_fd);
close(epoll_fd);
return 0;
}
```
这个代码实现了一个简单的 epoll 服务器,它监听端口 8888,并使用 epoll 实现了异步处理客户端连接和数据的功能。其中,set_nonblocking 函数用于将文件描述符设置为非阻塞模式,可以提高服务器的并发性能。在主循环中,使用 epoll_wait 函数等待事件,并根据事件类型进行处理。如果是新连接事件,使用 accept 函数接受新连接,并将新连接的文件描述符加入到 epoll 监听列表中;如果是数据到达事件,使用 read 函数读取数据,并将数据写回给客户端。
相关推荐
![pdf](https://img-home.csdnimg.cn/images/20210720083512.png)
![zip](https://img-home.csdnimg.cn/images/20210720083736.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)