Libevent多线程服务器-TCP

#include <iostream>
#include <event2/event.h>
#include <thread>
#include <winsock2.h>
#include <mutex>
#include <vector>
#include <future>

#pragma comment(lib, "Iphlpapi.lib")
#pragma comment(lib, "ws2_32.lib")
#pragma comment(lib, "wsock32.lib")
#pragma comment(lib, "event.lib")
#pragma comment(lib, "event_core.lib")
#pragma comment(lib, "event_extra.lib")
#pragma comment(lib, "bcrypt.lib")

int i=0;
std::mutex initMutex;

typedef struct ClientThreadBase {
    event_base *base{};
    SOCKET clientSocket{};
    std::thread thread;
    event *clientEvent{};
} clientThreadBase;

void workerThread(void *arg) {
    auto *p= (clientThreadBase *)arg;
    std::unique_lock<std::mutex> lock(initMutex);
    i++;
    lock.unlock();
    event_base_loop(p->base, 0);
}

void process(evutil_socket_t fd, short what, void *arg){
    auto *p= (clientThreadBase *)arg;
    char buffer[1024];
    int bytesReceived;
    while ((bytesReceived = recv(p->clientSocket, buffer, sizeof(buffer)-1, 0)) > 0) {
        buffer[bytesReceived] = '\0';
        std::cout << "Received from client: " << buffer << std::endl;
        send(p->clientSocket, buffer, bytesReceived, 0);
        DWORD currentThreadId = GetCurrentThreadId();
        std::cout << "Current thread ID: " << currentThreadId << std::endl;
    }
    if (bytesReceived == 0) {
        std::cout << "Client disconnected." << std::endl;
    } else {
        int error = WSAGetLastError();
        std::cerr << "recv error (" << error << ")" << std::endl;
    }
    closesocket(p->clientSocket);
}

void setup_thread(clientThreadBase *p,SOCKET &fd){
    p->base=event_base_new();
    p->clientEvent=event_new(p->base,fd,EV_READ|EV_PERSIST,process,p);
    event_add(p->clientEvent,nullptr);
}


int main() {
    WSADATA wsaData;
    if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
        std::cerr << "WSAStartup error" << std::endl;
        return -1;
    }
    SOCKET listenSocket = socket(AF_INET, SOCK_STREAM, 0);
    if (listenSocket == INVALID_SOCKET) {
        std::cerr << "socket error" << std::endl;
        return -1;
    }

    sockaddr_in serverAddr{};
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_addr.s_addr = INADDR_ANY;
    serverAddr.sin_port = htons(19870);
    if (bind(listenSocket, (sockaddr *)&serverAddr, sizeof(serverAddr)) == SOCKET_ERROR) {
        std::cerr << "bind error" << std::endl;
        return -1;
    }

    if (listen(listenSocket, SOMAXCONN) == SOCKET_ERROR) {
        std::cerr << "listen error" << std::endl;
        return -1;
    }

    std::vector<std::future<void>> futures;

    std::vector<clientThreadBase > g_threads{10};
    while (true) {
        sockaddr_in clientAddr{};
        socklen_t clientAddrLen = sizeof(clientAddr);
        SOCKET clientSocket = accept(listenSocket, (sockaddr *)&clientAddr, &clientAddrLen);
        if (clientSocket == INVALID_SOCKET) {
            std::cerr << "accept error" << std::endl;
            continue;
        }

        std::cout << "Accepted a client connection from " << inet_ntoa(clientAddr.sin_addr) << ":" << ntohs(clientAddr.sin_port) << std::endl;

        setup_thread(&g_threads[i],clientSocket);
        g_threads[i].clientSocket=clientSocket;
        g_threads[i].thread=std::thread(workerThread,&g_threads[i]);
        futures.push_back(std::async(std::launch::async, [&](){
            std::cout<<"join"<<std::endl;
            g_threads[i].thread.join();
        }));
        for (auto &f : futures) {
            f.wait();
        }
        std::cout<<"initThreadNum:"<<i<<std::endl;
    }
    
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

涛涛ALG

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值