Сокеты в С++. Как сохранять состояние, когда подключается клиент?

Задание:

Организовать взаимодействие типа клиент - сервер. К серверу одновременно может подключиться только один клиент. Остальные клиенты заносятся в очередь, и им высылается сообщение об ожидании освобождения сервера.

На самом деле, нужно сделать так, что бы когда подключился клиент, "состояние" сохранялось, а остальным клиентом отправить сообщение, что сейчас уже есть подключенный клиент...

  #undef UNICODE
    
    #define WIN32_LEAN_AND_MEAN
    
    #include <iostream>
    #include <windows.h>
    #include <winsock2.h>
    #include <ws2tcpip.h>
    #include <stdlib.h>
    #include <stdio.h>

    // Need to link with Ws2_32.lib
    #pragma comment (lib, "Ws2_32.lib")
    // #pragma comment (lib, "Mswsock.lib")
    
    #include "ServerS.h"
    
    
    // фция для обрезки строки
    char* slice(char* s, int from, int to)
    {
        int j = 0;
        for (int i = from; i <= to; ++i)
            s[j++] = s[i];
        s[j] = 0;
        return s;
    }
    
    int startServer(std::string(*func)(std::string), const char* addresses, const char* port = "27015")
    {
        // Размер принимаемого буфера
        const int DEFAULT_BUFLEN = 512;
    
        WSADATA wsaData;
        int iResult;
    
        SOCKET ListenSocket = INVALID_SOCKET;
        SOCKET ClientSocket = INVALID_SOCKET;
    
        struct addrinfo* result = NULL;
        struct addrinfo hints;
    
        int iSendResult;
        char recvbuf[DEFAULT_BUFLEN];
        int recvbuflen = DEFAULT_BUFLEN;
    
        // Инициализация Winsock
        iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
        if (iResult != 0) {
            printf("WSAStartup failed with error: %d\n", iResult);
            return 1;
        }
    
        ZeroMemory(&hints, sizeof(hints));
        hints.ai_family = AF_INET;
        hints.ai_socktype = SOCK_STREAM;
        hints.ai_protocol = IPPROTO_TCP;
        hints.ai_flags = AI_PA

SSIVE;

    // адрес сервера и порт
    iResult = getaddrinfo(addresses, port, &hints, &result);
    if (iResult != 0) {
        printf("getaddrinfo failed with error: %d\n", iResult);
        WSACleanup();
        return 1;
    }

    // Создание сокета для подключения к серверу
    ListenSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
    if (ListenSocket == INVALID_SOCKET) {
        printf("socket failed with error: %ld\n", WSAGetLastError());
        freeaddrinfo(result);
        WSACleanup();
        return 1;
    }

    // Установка сокета для прослушивания TCP
    iResult = bind(ListenSocket, result->ai_addr, (int)result->ai_addrlen);
    if (iResult == SOCKET_ERROR) {
        printf("bind failed with error: %d\n", WSAGetLastError());
        freeaddrinfo(result);
        closesocket(ListenSocket);
        WSACleanup();
        return 1;
    }

    freeaddrinfo(result);

    iResult = listen(ListenSocket, SOMAXCONN);
    if (iResult == SOCKET_ERROR) {
        printf("listen failed with error: %d\n", WSAGetLastError());
        closesocket(ListenSocket);
        WSACleanup();
        return 1;
    }


    // Цикл для прослушки
    while (true)
    {
        // Принять клиентский сокет
        ClientSocket = accept(ListenSocket, NULL, NULL);
        if (ClientSocket == INVALID_SOCKET) {
            printf("accept failed with error: %d\n", WSAGetLastError());
            closesocket(ListenSocket);
            WSACleanup();
            return 1;
        }

        // No longer need server socket
        // closesocket(ListenSocket);

        std::string strResult = "";
        // Принимать до тех пор, пока одноранговый узел не отключит соединение
        do {

            iResult = recv(ClientSocket, recvbuf, recvbuflen, 0);
            if (iResult > 0) {
                strResult += slice(recvbuf, 0, iResult - 1);
            }
            else if (iResult == 0)
                printf("\nConnection closing...\n");
            else {
                printf("recv failed with error: %d\n", WSAGetLastError());
                closesocket(ClientSocket);
                WSACleanup();
                return 1;
            }

        } while (iResult > 0);

        std::cout << "Сообщение от клиента: " << strResult << std::endl;


        // Проверка на стоп слова
        if (strResult == "/stopserver")
        {
            std::cout << std::endl << "Остановка сервера..." << std::endl;
            break;
        }

        // Обработка сообщения:
        std::string str = func(strResult);
        char* cstr = &str[0];

        // Отправить результат обратно отправителю
        iSendResult = send(ClientSocket, cstr, (int)strlen(cstr), 0);
        if (iSendResult == SOCKET_ERROR)
        {
            printf("send failed with error: %d\n", WSAGetLastError());
            closesocket(ClientSocket);
            WSACleanup();
            return 1;
        }

        // отключите соединение, так как мы закончили
       iResult = shutdown(ClientSocket, SD_SEND);
        if (iResult == SOCKET_ERROR) {
            printf("shutdown failed with error: %d\n", WSAGetLastError());
            closesocket(ClientSocket);
            WSACleanup();
            return 1;
        }

    }
    // cleanup
    closesocket(ClientSocket);
    WSACleanup();
    return 0;
}

Ответы (0 шт):