怎么做电脑端网站设计稿,外贸公司名字大全洋气,百度推广账户怎么开,网站开发是什么经营范围IO多路复用通常用于处理单进程高并发#xff0c;在Linux中#xff0c;一切皆文件#xff0c;一个socket连接会对应一个文件描述符#xff0c;在监听多个文件描述符的状态应用中epoll相对于select和poll效率更高
epoll本质是系统在内核维护了一颗红黑树#xff0c;监听的文…IO多路复用通常用于处理单进程高并发在Linux中一切皆文件一个socket连接会对应一个文件描述符在监听多个文件描述符的状态应用中epoll相对于select和poll效率更高
epoll本质是系统在内核维护了一颗红黑树监听的文件描述符会作为新的节点插入红黑树epoll会等待有状态变化的节点记录在链表里然后拷贝到用户所给的数组里面返回出来
以下是一个独立的服务端代码可以补充业务代码进行具体使用
sever.h
//
// Created by YEZI on 2024/5/24.
//#ifndef SEVER_H
#define SEVER_H
#include iostream
#include cstdlib
#include unistd.h
#include sys/epoll.h
#include sys/socket.h
#include netinet/in.h
#include arpa/inet.h
#include sstream
#define MAX_EVENTS 8
#define PORT 8888
#define BUFFER_SIZE 512
#define BACKLOG_SIZE 16 // 请求队列最大长度class Sever {
private:uint16_t port;int server_fd -1;int epoll_fd -1;sockaddr_in server_addr{}, client_addr{};socklen_t client_addr_len sizeof(client_addr);epoll_event event{}, events[MAX_EVENTS]{};public:explicit Sever(uint16_t port PORT): port(port) {// 创建套接字// AF_INET : 表示使用 IPv4 地址 可选参数// SOCK_STREAM 表示使用面向连接的数据传输方式// IPPROTO_TCP 表示使用 TCP 协议server_fd socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);if (server_fd -1) {std::cerr Failed to create socket\n;exit(EXIT_FAILURE);}// 设置服务器地址server_addr.sin_family AF_INET; // IPv4server_addr.sin_addr.s_addr INADDR_ANY; // INADDR_ANY0.0.0.0 表示本机所有IP地址server_addr.sin_port htons(PORT);// 绑定套接字if (bind(server_fd, (sockaddr *) server_addr, sizeof(server_addr)) -1) {std::cerr Failed to bind socket\n;exit(EXIT_FAILURE);}// 监听套接字if (listen(server_fd, BACKLOG_SIZE) -1) {std::cerr Failed to listen on socket\n;exit(EXIT_FAILURE);}// 创建 epoll 实例epoll_fd epoll_create1(0); // flag设置为0同epoll_create()if (epoll_fd -1) {std::cerr Failed to create epoll instance\n;exit(EXIT_FAILURE);}// 将服务器套接字添加到 epoll 实例中event.events EPOLLIN | EPOLLET; // 监听事件类型 EPOLLIN表示有数据可读 EPOLLET表示边缘触发仅在状态变化时通知event.data.fd server_fd;if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, server_fd, event) -1) {std::cerr Failed to add server socket to epoll\n;exit(EXIT_FAILURE);}std::cout Server started. Listening on port PORT ...\n;}void run() {while (true) {// 使用 epoll 等待事件 参数timeout为等待时间-1等死int num_ready epoll_wait(epoll_fd, events, MAX_EVENTS, -1);if (num_ready -1) {std::cerr Error in epoll_wait\n;exit(EXIT_FAILURE);}for (int i 0; i num_ready; i) {if (events[i].data.fd server_fd) {// 有新的连接请求int client_fd accept(server_fd, (sockaddr *) client_addr, client_addr_len);if (client_fd -1) {std::cerr Failed to accept client connection\n;continue;}std::cout New connection from inet_ntoa(client_addr.sin_addr) : ntohs(client_addr.sin_port) std::endl;// 将新的客户端套接字添加到 epoll 实例中event.events EPOLLIN | EPOLLET;event.data.fd client_fd;if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, client_fd, event) -1) {std::cerr Failed to add client socket to epoll\n;exit(EXIT_FAILURE);}} else {// 有数据到达现有客户端套接字char buffer[BUFFER_SIZE]{};ssize_t bytes_received recv(events[i].data.fd, buffer, BUFFER_SIZE, 0);if (bytes_received 0) {if (bytes_received 0) {// 客户端关闭连接std::cout Client disconnected\n;} else {std::cerr Error in recv\n;}// 关闭客户端套接字并从 epoll 实例中移除close(events[i].data.fd);epoll_ctl(epoll_fd, EPOLL_CTL_DEL, events[i].data.fd, nullptr);} else {// 接收到数据原样发送回客户端此处为业务代码补充处send(events[i].data.fd, buffer, bytes_received, 0);std::istringstream iss(buffer);std::string data;while (iss data) {std::cout data ;}std::coutstd::endl;}}}}}~Sever() {// 关闭服务器套接字和 epoll 实例close(server_fd);close(epoll_fd);}
};
#endif //SEVER_Hmain.cpp
#includesever.h
int main() {Sever sever;sever.run();
}简单测试服务端打开Linux终端用一下命令连接服务器后即可传输数据
telnet localhost 8888