#include <iostream>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/epoll.h>
#include <fcntl.h>
#include <cstring>
#include <vector>
#define PORT 8080
#define MAX_EVENTS 10
#define BUFFER_SIZE 1024
// 创建非阻塞 socket
int create_server_socket() {
int server_fd = socket(AF_INET, SOCK_STREAM, 0);
if (server_fd == -1) {
std::cerr << "Socket creation failed!" << std::endl;
return -1;
}
// 设置 socket 为非阻塞模式
int flags = fcntl(server_fd, F_GETFL, 0);
fcntl(server_fd, F_SETFL, flags | O_NONBLOCK);
sockaddr_in server_addr;
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = INADDR_ANY;
server_addr.sin_port = htons(PORT);
if (bind(server_fd, (struct sockaddr*)&server_addr, sizeof(server_addr)) < 0) {
std::cerr << "Binding failed!" << std::endl;
close(server_fd);
return -1;
}
if (listen(server_fd, 3) < 0) {
std::cerr << "Listen failed!" << std::endl;
close(server_fd);
return -1;
}
return server_fd;
}
int main() {
int server_fd = create_server_socket();
if (server_fd == -1) {
return 1;
}
// 创建 epoll 实例
int epoll_fd = epoll_create1(0);
if (epoll_fd == -1) {
std::cerr << "Epoll create failed!" << std::endl;
close(server_fd);
return 1;
}
// 将 server_fd 加入 epoll 监听
struct epoll_event event;
event.events = EPOLLIN;
event.data.fd = server_fd;
if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, server_fd, &event) == -1) {
std::cerr << "Epoll_ctl failed!" << std::endl;
close(server_fd);
close(epoll_fd);
return 1;
}
std::vector<struct epoll_event> events(MAX_EVENTS);
while (true) {
// 等待事件发生
int num_events = epoll_wait(epoll_fd, events.data(), MAX_EVENTS, -1); // 阻塞直到有事件
if (num_events == -1) {
std::cerr << "Epoll wait failed!" << std::endl;
break;
}
// 处理所有发生的事件
for (int i = 0; i < num_events; ++i) {
if (events[i].data.fd == server_fd) {
// 新的客户端连接
sockaddr_in client_addr;
socklen_t client_len = sizeof(client_addr);
int client_fd = accept(server_fd, (struct sockaddr*)&client_addr, &client_len);
if (client_fd == -1) {
std::cerr << "Accept failed!" << std::endl;
} else {
std::cout << "New client connected!" << std::endl;
// 设置新连接为非阻塞
int flags = fcntl(client_fd, F_GETFL, 0);
fcntl(client_fd, F_SETFL, flags | O_NONBLOCK);
// 将 client_fd 添加到 epoll 中
event.events = EPOLLIN | EPOLLET; // 使用边缘触发
event.data.fd = client_fd;
if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, client_fd, &event) == -1) {
std::cerr << "Epoll_ctl failed!" << std::endl;
close(client_fd);
}
}
} else if (events[i].events & EPOLLIN) {
// 客户端发送数据
int client_fd = events[i].data.fd;
char buffer[BUFFER_SIZE];
ssize_t bytes_read = read(client_fd, buffer, sizeof(buffer));
if (bytes_read > 0) {
std::cout << "Received data: " << std::string(buffer, bytes_read) << std::endl;
// 向客户端发送数据
write(client_fd, "Hello, client!", 14);
} else if (bytes_read == 0) {
// 客户端关闭连接
std::cout << "Client disconnected!" << std::endl;
// 从 epoll 中删除 client_fd
if (epoll_ctl(epoll_fd, EPOLL_CTL_DEL, client_fd, nullptr) == -1) {
std::cerr << "Failed to remove client_fd from epoll!" << std::endl;
}
close(client_fd);
} else {
std::cerr << "Read error!" << std::endl;
close(client_fd);
}
}
}
}
// 清理资源
close(server_fd);
close(epoll_fd);
return 0;
}