이전버전에서 쓰레드를 추가했다.
#include <iostream>
#include <winsock2.h>
#include <WS2tcpip.h>
#include <array>
#include <thread>
#include <vector>
#pragma comment(lib, "ws2_32.lib")
auto EchoHandler(SOCKET clientSocket)->void{
int receiveSize;
std::array<char, 128> receivedBuffer;
while ((receiveSize = ::recv(clientSocket, receivedBuffer.data(), receivedBuffer.size(), 0)) > 0) {
::send(clientSocket, receivedBuffer.data(), receiveSize, 0);
std::cout.write(receivedBuffer.data(), receiveSize);
std::cout << std::endl;
receivedBuffer.fill(0);
}
if (receiveSize == SOCKET_ERROR) {
std::cerr << "Receive failed." << std::endl;
}
::closesocket(clientSocket);
std::cout << "클라이언트가 연결이 끊겼습니다." << std::endl;
}
int main() {
WSADATA wsaData;
if (::WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
std::cerr << "WSAStartup failed." << std::endl;
return 1;
}
SOCKET listenSocket = ::socket(AF_INET, SOCK_STREAM, 0);
if (listenSocket == INVALID_SOCKET) {
std::cerr << "Failed to create socket." << std::endl;
::WSACleanup();
return 1;
}
constexpr uint16_t port = 8888;
SOCKADDR_IN serverAddress{
.sin_family = AF_INET,
.sin_port = htons(port),
.sin_addr{.S_un{.S_addr = htonl(INADDR_ANY)}},
//.sin_addr{.S_un{.S_addr = inet_addr("192.168.35.154")}},
};
if (::bind(listenSocket, reinterpret_cast<SOCKADDR*>(&serverAddress), sizeof(serverAddress)) == SOCKET_ERROR) {
std::cerr << "Bind failed." << std::endl;
::closesocket(listenSocket);
::WSACleanup();
return 1;
}
if (::listen(listenSocket, SOMAXCONN) == SOCKET_ERROR) {
std::cerr << "Listen failed." << std::endl;
::closesocket(listenSocket);
::WSACleanup();
return 1;
}
SOCKET clientSocket;
SOCKADDR_IN clientAddress;
int clientAddressSize = sizeof(clientAddress);
std::vector<std::thread> echoHandlers;
while ((clientSocket = ::accept(listenSocket,
reinterpret_cast<SOCKADDR*>(&clientAddress),
&clientAddressSize)) != INVALID_SOCKET) {
std::cout << "새 클라이언트가 연결되었습니다." << std::endl;
echoHandlers.emplace_back(EchoHandler, clientSocket);
}
for (auto &handler : echoHandlers) {
if(handler.joinable())
handler.join();
}
::closesocket(listenSocket);
::WSACleanup();
return 0;
}
'C++ > 네트워크' 카테고리의 다른 글
윈도우 소켓 깔끔하게 작성해보기 (0) | 2025.03.11 |
---|---|
다시써보는 에코클라이언트 Linux 버전 (0) | 2024.06.01 |
다시 써보는 에코서버 window 버전 (0) | 2024.06.01 |