#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;
}
05-18
1万+