#include <iostream>
#include <thread>
#include <vector>
#include <memory>
#include <functional>
#include <mutex>
#include <condition_variable>
#include <queue>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <fcntl.h>
#include "reactor.h"
// 任务结构体
struct Task {
int fd; // 文件描述符
sockaddr_in addr; // 客户端地址
Task(int fd_, sockaddr_in addr_) : fd(fd_), addr(addr_) {}
};
// 线程池类
class ThreadPool {
public:
ThreadPool(size_t size) : stop_(false) {
for (size_t i = 0; i < size; ++i) {
threads_.emplace_back(std::bind(&ThreadPool::run, this));
}
}
//等待线程都执行完成
~ThreadPool() {
{
std::unique_lock<std::mutex> lock(mutex_);
stop_ = true;
cond_.notify_all();
}
for (auto& t : threads_) {
t.join();
}
}
void add_task(Task task) {
std::unique_lock<std::mutex> lock(mutex_);
tasks_.emplace(task);
cond_.notify_one();
}
private:
void run() {
while (!stop_) {
std::unique_lock<std::mutex> lock(mutex_);
while (tasks_.empty() && !stop_) {
cond_.wait(lock);
}
if (!tasks_.empty()) {
auto task = tasks_.front();
tasks_.pop();
lock.unlock();
// 处理任务
handle_task(task);
lock.lock();
}
}
}
void handle_task(Task task) {
// 处理客户端请求
char buf[1024] = {0};
int n = read(task.fd, buf, sizeof(buf));
if (n < 0) {
std::cerr << "read error" << std::endl;
} else if (n == 0) {
std::cout << "client closed" << std::endl;
} else {
std::cout << "recv: " << buf << std::endl;
write(task.fd, buf, n);
}
close(task.fd);
}
private:
std::vector<std::thread> threads_; // 工作线程
std::queue<Task> tasks_; // 任务队列
std::mutex mutex_; // 互斥锁
std::condition_variable cond_; // 条件变量
bool stop_; // 停止标志
};
// TCP服务器类
class TcpServer {
public:
TcpServer(int port) : port_(port) {}
void start() {
// 创建两个reactor实例
Reactor reactor1;
Reactor reactor2;
// 创建线程池
ThreadPool pool(2);
// 注册监听socket
int listen_fd = socket(AF_INET, SOCK_STREAM, 0);
if (listen_fd < 0) {
std::cerr << "socket error" << std::endl;
return;
}
fcntl(listen_fd, F_SETFL, O_NONBLOCK);
int optval = 1;
setsockopt(listen_fd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));
sockaddr_in addr = {0};
addr.sin_family = AF_INET;
addr.sin_port = htons(port_);
addr.sin_addr.s_addr = htonl(INADDR_ANY);
if (bind(listen_fd, (sockaddr*)&addr, sizeof(addr)) < 0) {
std::cerr << "bind error" << std::endl;
return;
}
if (listen(listen_fd, SOMAXCONN) < 0) {
std::cerr << "listen error" << std::endl;
return;
}
reactor1.register_event(listen_fd, EventType::kReadEvent,
std::bind(&TcpServer::handle_accept, this, listen_fd, std::ref(reactor2), std::ref(pool)));
// 启动两个reactor实例和两个工作线程
std::thread thread1(std::bind(&Reactor::loop, &reactor1));
std::thread thread2(std::bind(&Reactor::loop, &reactor2));
thread1.detach();
thread2.detach();
// 进入主线程,等待退出信号
std::unique_lock<std::mutex> lock(mutex_);
cond_.wait(lock);
}
void stop() {
std::unique_lock<std::mutex> lock(mutex_);
cond_.notify_all();
}
private:
void handle_accept(int listen_fd, Reactor& reactor, ThreadPool& pool) {
sockaddr_in addr = {0};
socklen_t addrlen = sizeof(addr);
int conn_fd = accept(listen_fd, (sockaddr*)&addr, &addrlen);
if (conn_fd < 0) {
std::cerr << "accept error" << std::endl;
return;
}
fcntl(conn_fd, F_SETFL, O_NONBLOCK);
std::cout << "client connected: " << inet_ntoa(addr.sin_addr) << ":" << ntohs(addr.sin_port) << std::endl;
pool.add_task(Task(conn_fd, addr));
}
private:
int port_; // 监听端口
std::mutex mutex_; // 互斥锁
std::condition_variable cond_; // 条件变量
};
int main() {
TcpServer server(8000);
server.start();
return 0;
}
11-09
1683
“相关推荐”对你有帮助么?
-
非常没帮助
-
没帮助
-
一般
-
有帮助
-
非常有帮助
提交