1 year ago

#365496

test-img

John Doe

C++ multithreaded Winsock server doesn't behave like expected

I am trying to create a simple multithreaded server in C++ for Windows using Winsock. I am facing a problem that I do not know how to solve. I expect my server to be able to serve multiple clients at once. Multiple clients should be able to connect to the server and query the server and get the following response back: "This is a message from the server."

Client 1 connects and gets the response successfully. Client 2 connects and now Client 1 does not receive the reponse anymore! Only Client 2 receives a response. I expect both Client 1 and Client 2 to be able to query the server and get a response from the server at the same time.

#define WIN32_LEAN_AND_MEAN
#include <iostream>
#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <chrono>
#include <thread>
#include <string>
#pragma comment (lib, "Ws2_32.lib")

#define DEFAULT_IP "192.168.11.108"
#define DEFAULT_PORT "12345"
#define DEFAULT_BUFLEN 1024

void ServeClient(const SOCKET* s) {
    std::thread::id threadId = std::this_thread::get_id();
    
    std::cout << "Client with thread id " << threadId << " connected to the server." << std::endl;

    char receiveBuffer[DEFAULT_BUFLEN];
    int  receiveBufferLength = DEFAULT_BUFLEN;
    int  receiveResult = SOCKET_ERROR;

    char sendBuffer[] = "This is a message from the server.";
    int  sendBufferLength = sizeof(sendBuffer) / sizeof(sendBuffer[0]);
    int  sendResult = SOCKET_ERROR;

    while (true) {
        receiveResult = recv(*s, receiveBuffer, receiveBufferLength, 0);
        if (receiveResult <= 0)
            break;
        sendResult = send(*s, sendBuffer, sendBufferLength, 0);
        std::this_thread::sleep_for(std::chrono::milliseconds(100));
    }  
   
    closesocket(*s);
    
    std::cout << "Client with thread id " << threadId << " disconnected from the server." << std::endl;
}
int main() {
    int result;
    WSADATA wsaData;

    struct addrinfo* getAddrInfoResult = NULL;
    struct addrinfo getAddrInfoHints;

    result = WSAStartup(MAKEWORD(2, 2), &wsaData);
    if (result != 0) {
        std::cout << "WSAStartup() failed with error code: " << result;
        return 1;
    }

    ZeroMemory(&getAddrInfoHints, sizeof(getAddrInfoHints));
    getAddrInfoHints.ai_family = AF_INET;
    getAddrInfoHints.ai_socktype = SOCK_STREAM;
    getAddrInfoHints.ai_protocol = IPPROTO_TCP;
    getAddrInfoHints.ai_flags = AI_PASSIVE;

    result = getaddrinfo(DEFAULT_IP, DEFAULT_PORT, &getAddrInfoHints, &getAddrInfoResult);
    if (result != 0) {
        std::cout << "getaddrinfo() failed with error code: " << result;
        WSACleanup();
        return 1;
    }

    SOCKET ServerSocket = socket(getAddrInfoResult->ai_family, getAddrInfoResult->ai_socktype, getAddrInfoResult->ai_protocol);
    if (ServerSocket == INVALID_SOCKET) {
        std::cout << "socket() failed with error code: " << WSAGetLastError();
        freeaddrinfo(getAddrInfoResult);
        WSACleanup();
        return 1;
    }

    result = bind(ServerSocket, getAddrInfoResult->ai_addr, (int)getAddrInfoResult->ai_addrlen);
    if (result == SOCKET_ERROR) {
        std::cout << "bind() failed with error code: " << WSAGetLastError();
        freeaddrinfo(getAddrInfoResult);
        closesocket(ServerSocket);
        WSACleanup();
        return 1;
    }

    freeaddrinfo(getAddrInfoResult);

    result = listen(ServerSocket, SOMAXCONN);
    if (result == SOCKET_ERROR) {

        std::cout << "listen() failed with error code: " << WSAGetLastError();
        closesocket(ServerSocket);
        WSACleanup();
        return 1;
    }

    std::cout << "Server listening..." << std::endl;

    while (true)
    {
        SOCKET ClientSocket = accept(ServerSocket, NULL, NULL);

        if (ClientSocket != INVALID_SOCKET) {
            std::thread(ServeClient, &ClientSocket).detach();
        }
        std::this_thread::sleep_for(std::chrono::milliseconds(250));
    }
    
    closesocket(ServerSocket);
    WSACleanup();
    return 0;
}

Appreciate it if someone can help. Thank you.

c++

multithreading

winsock

stdthread

0 Answers

Your Answer

Accepted video resources