epoll 版 高并发服务器

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <arpa/inet.h>
#include <sys/epoll.h>
#include <errno.h>
#include <ctype.h>
int main()
{
 // 1 创建套接字
 int lfd = socket(AF_INET, SOCK_STREAM, 0);
 // 2 端口复用
 int opt = 1;
 setsockopt(lfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
 // 3 绑定
 struct sockaddr_in server_addr;
 bzero(&server_addr, sizeof(server_addr));
 server_addr.sin_family = AF_INET;
 server_addr.sin_port = htons(8888);
 server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
 bind(lfd, (struct sockaddr*)&server_addr, sizeof(server_addr));
 // 4 同时访问上限
 listen(lfd, 128);
 // 5 创建epoll句柄
 int epfd = epoll_create(1000); 
// lfd结点上树
 struct epoll_event tep;
 tep.data.fd = lfd;
 tep.events = EPOLLIN;
 epoll_ctl(epfd, EPOLL_CTL_ADD, lfd, &tep);
 // 6 监听读事件
 int cfd; // 定义lfd通信描述符
 struct sockaddr_in client_addr;
 socklen_t client_len = sizeof(client_addr); // 用于接收客户端信息
 struct epoll_event ep[1000]; // 用于接收变化的结点
 while(1)
 {
     int nready = epoll_wait(epfd, ep, 1000, -1); // 阻塞等待结点变化
     for(int i = 0; i < nready; i++)
     {
         if(!(ep[i].events & EPOLLIN))
             continue; // 因为只要有事件发生,就会计入ep[]中,如果不是读事件,继续循环
         if(ep[i].data.fd == lfd)
         {
             // 是连接请求
             cfd = accept(lfd, (struct sockaddr*)&client_addr, &client_len);
             char ip[16] = {0};
             printf("conn from %s at %d\n", inet_ntop(AF_INET, &client_addr.sin_addr.s_addr, ip, sizeof(ip)), ntohs(client_addr.sin_port)); // 打印客户端信息
             // cfd 上树
             tep.data.fd = cfd;
             tep.events = EPOLLIN;
             epoll_ctl(epfd, EPOLL_CTL_ADD, cfd, &tep);
         }
         else
         {
             // 普通读事件
             int sockfd = ep[i].data.fd;
             char buf[BUFSIZ] = {0};
             int n = read(sockfd, buf, sizeof(buf));
             if(n < 0) 
             { 
                 perror("read err");
                 epoll_ctl(epfd, EPOLL_CTL_DEL, sockfd, NULL); // 下树
                 close(sockfd);
             }
             else if(n == 0) 
             { 
                 printf("client[%d] closed\n", sockfd);
                 epoll_ctl(epfd, EPOLL_CTL_DEL, sockfd, NULL); // 下树
                 close(sockfd);
             }
             else
             {
                 write(sockfd, buf, n);
                 write(STDOUT_FILENO,buf, n);
             }
         } // 普通读事件结束
     } // for循环,解决变化结点事件结束
} // while循环结束
 close(lfd);
 close(epfd);
 return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是使用epoll和线程池实现高并发服务器的C++11代码示例: ```cpp #include <iostream> #include <thread> #include <vector> #include <queue> #include <mutex> #include <condition_variable> #include <sys/epoll.h> #include <unistd.h> #define MAX_EVENTS 100 #define THREAD_POOL_SIZE 10 std::mutex mtx; std::condition_variable cv; std::queue<int> taskQueue; void workerThread() { while (true) { std::unique_lock<std::mutex> lock(mtx); cv.wait(lock, [] { return !taskQueue.empty(); }); int fd = taskQueue.front(); taskQueue.pop(); // 处理任务,这里可以根据具体需求进行处理 lock.unlock(); // 继续监听其他事件 } } int main() { // 创建epoll句柄 int epoll_fd = epoll_create(1); if (epoll_fd == -1) { std::cerr << "Failed to create epoll" << std::endl; return 1; } // 创建线程池 std::vector<std::thread> threadPool; for (int i = 0; i < THREAD_POOL_SIZE; ++i) { threadPool.emplace_back(workerThread); } // 添加监听事件到epoll句柄 struct epoll_event event; event.events = EPOLLIN; event.data.fd = /* 监听的文件描述符 */; if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, /* 监听的文件描述符 */, &event) == -1) { std::cerr << "Failed to add event to epoll" << std::endl; return 1; } // 开始监听事件 struct epoll_event events[MAX_EVENTS]; while (true) { int num_events = epoll_wait(epoll_fd, events, MAX_EVENTS, -1); if (num_events == -1) { std::cerr << "Failed to wait for events" << std::endl; return 1; } for (int i = 0; i < num_events; ++i) { if (events[i].events & EPOLLIN) { // 处理读事件,将任务添加到任务队列 std::lock_guard<std::mutex> lock(mtx); taskQueue.push(events[i].data.fd); cv.notify_one(); } } } // 清理资源 close(epoll_fd); for (auto& thread : threadPool) { thread.join(); } return 0; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值