epoll线程池实现简单TCP并发文件服务器

epoll+线程池 简单TCP并发文件服务器
epoll部分代码在libevent的源码上修改的
线程池部分参考 https://www.cnblogs.com/yangang92/p/5485868.html

操作过程:将所有文件拷贝到Linux目录下(改源码中存放文件的路径),
make命令进行编译,打开(多个)终端./server运行服务器端,./client运行客户端,
然后在客户端下输入操作:
update xxx.txt(这个文件要在CLI_PATH路径下)或者 download xxx.txt(这个文件要在服务器PATH的路径下)

大致的思路:开两个线程池,一个用于任务列表维护,一个用于任务列表处理
服务器端用epoll监听是否有连接或者已连接的fd有无数据(一个type表示客户端要进行的操作)发来,
接收到type后,根据type的值确定客户端要进行的操作(上传或者下载)
然后对任务列表维护线程池发放任务(将数据包放到任务列表里),再对任务列表处理线程池发放任务(对任务列表的数据包进行处理)

源码地址:https://github.com/KronosCzj/epollDocServer

不足的地方:1.任务列表维护线程池里的线程每次要对客户端的整个操作(比如说要把客户端发来的一个文件全部读完)执行完才结束,导致并发量决定于线程池线程数目,
当用户数目远大于线程池数目时,超过线程池线程数目后面的用户的操作要等前面用户的操作结束才能开始,
应该将列表维护线程池里的线程的任务的粒度缩小到一个包的粒度,轮流处理用户的操作,然后放入任务列表
2.这个版本只是一个大致功能的实现,对一些细节并没有实现,比如上传服务器已有的文件会继续再这个文件末尾追加等等
3.太大的文件传输不了,客户端只是简单的send和recv,应该用同样的多线程维护一个任务列表来进行数据的传输的
4.代码封包解包部分重复较多

//文章由笔者原创,记录和分享自己的学习历程,转载请注明出处

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 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、付费专栏及课程。

余额充值