Почему при групповой рассылке, при отправке клиентом сообщение, оно приходит только серверу, а не всем клиентам? C++

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

Server:

#include "Headers.h"

DWORD WINAPI ReceiveMess(LPVOID lpParameter);

int main()
{
    WinSockInitializer* initializer = nullptr;
    HANDLE hEvent = CreateEvent(NULL, FALSE /* ручной сброс события */, FALSE /* несигнальное состояние */, TEXT("{2BA7C99B-D9F7-4485-BB3F-E4735FFEF1789}"));

    try {

        initializer = WinSockInitializer::GetInstance();

        UDPClient* client = new UDPClient;
        cout << "Client started" << endl;

        client->SetName();

        char ip[50];
        cout << "Enter an ip: ";
        cin >> ip;

        int port;
        cout << "Enter a port: ";
        cin >> port;

        client->bind(ip, port);

        char groupIp[255];
        cout << "Enter a group ip: ";
        cin >> groupIp;

        client->setsockopt(groupIp);

        HANDLE hReceiveMess = CreateThread(NULL, 0, ReceiveMess, client, 0, NULL);
        CloseHandle(hReceiveMess);

        if (WaitForSingleObject(hEvent, INFINITE) == WAIT_OBJECT_0)
        {
            while (true)
            {
                char request[1024] = "";
                char text[1024] = "";
                _getch();
                cout << "Enter request text: ";
                cin.ignore();
                cin.getline(text, 1024);
                sprintf_s(request, "Client %s: %s", client->GetName(), text);

                if (strstr(request, "EXIT") != 0)
                {
                    break;
                }

                client->sendto(request, strlen(request) + 1, client->GetAddrFrom());
            }
        }

        client->shutdown();
        delete initializer;
        delete client;
    }
    catch (SocketException& ex)
    {
        cout << ex.what() << endl;

        if (initializer != nullptr)
        {
            delete initializer;
        }
    }
    system("pause");
}

DWORD __stdcall ReceiveMess(LPVOID lpParameter)
{
    HANDLE hEvent = OpenEvent(EVENT_ALL_ACCESS, 0, TEXT("{2BA7C99B-D9F7-4485-BB3F-E4735FFEF1789}"));
    UDPClient* client = (UDPClient*)lpParameter;

    while (true)
    {
        try
        {
            client->recvfrom();
            cout << client->GetRecvbuf() << endl;
        }
        catch (...)
        {
            cout << "ERROR R:" << WSAGetLastError() << endl;
            cout << client->GetRecvbuf() << endl;
        }
        SetEvent(hEvent);
    }

    delete client;
    return 0;
}

Client:

#pragma comment(lib, "UDPSockets.lib")
#include "Headers.h"

DWORD WINAPI ReceiveMess(LPVOID lpParameter);

int main()
{
    HANDLE hEvent = CreateEvent(NULL, FALSE /* ручной сброс события */, TRUE /* сигнальное состояние */, TEXT("{2BA7C99B-D9F7-4485-BB3F-E4735FFEF1589}"));
    WinSockInitializer* initializer = nullptr;

    try {

        initializer = WinSockInitializer::GetInstance();

        UDPClient* client = new UDPClient;
        cout << "Client started" << endl;

        client->SetName();

        char ip[50];
        cout << "Enter an ip: ";
        cin >> ip;

        int port;
        cout << "Enter a port: ";
        cin >> port;

       _addrTo.sin_family = AF_INET;
       _addrTo.sin_port = htons(port);
       inet_pton(AF_INET, ipAddress.c_str(), &_addrTo.sin_addr.s_addr);

        HANDLE hReceiveMess = CreateThread(NULL, 0, ReceiveMess, client, 0, NULL);
        CloseHandle(hReceiveMess);

        while (true)
        {
            char request[1024] = "";
            char text[1024] = "";
            _getch();
            cout << "Enter request text: ";
            cin.ignore();
            cin.getline(text, 1024);
            sprintf_s(request, "Client %s: %s", client->GetName(), text);

            if (strstr(request, "EXIT") != 0)
            {
                break;
            }

            client->sendto(request, strlen(request) + 1, client->GetAddrTo());
        }


        client->shutdown();
        delete initializer;
        delete client;
    }
    catch (SocketException& ex)
    {
        cout << ex.what() << endl;

        if (initializer != nullptr)
        {
            delete initializer;
        }
    }
    system("pause");
}

DWORD __stdcall ReceiveMess(LPVOID lpParameter)
{
    HANDLE hEvent = OpenEvent(EVENT_ALL_ACCESS, 0, TEXT("{2BA7C99B-D9F7-4485-BB3F-E4735FFEF1589}"));
    UDPClient* client = (UDPClient*)lpParameter;

    while (true)
    {
        try
        {
            client->recvfrom();
            cout << client->GetRecvbuf() << endl;
        }
        catch (...)
        {
             //cout << "ERROR R:" << WSAGetLastError() << endl;
             //cout << client->GetRecvbuf() << endl;
        }
    }

    delete client;
    return 0;
}

Методы:


void UDPClient::bind(string ipAddress, unsigned short port)
{
    //инициализация структуры для указания ip адреса и порта, с которым мы хотим соединиться
    _addrTo.sin_family = AF_INET;
    _addrTo.sin_port = htons(port);
    //inet_pton(AF_INET, ipAddress.c_str(), &_addrTo.sin_addr.s_addr);
    _addrTo.sin_addr.s_addr = htonl(INADDR_ANY);

    if (::bind(_clientSocket, (SOCKADDR*)&_addrTo, sizeof(_addrTo)) != NO_ERROR)
    {
        throw SocketException("bind failed with error ");
    }
}

void UDPClient::setsockopt(char* groupIp)
{
    inet_pton(AF_INET, groupIp, &_mreq.imr_multiaddr.s_addr);
    _mreq.imr_interface.s_addr = htonl(INADDR_ANY);

    if (::setsockopt(_clientSocket, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char*)&_mreq, sizeof(_mreq)) != NO_ERROR)
    {
        throw SocketException("socket failed with error: ");
    }
}

void UDPClient::recvfrom()
{
    int addrFromSize = sizeof(_addrFrom);
    int result = ::recvfrom(_clientSocket, _recvbuf, 1024, 0, (SOCKADDR*)&_addrFrom, &addrFromSize);

    if (result == SOCKET_ERROR)
    {
        throw SocketException("recvfrom failed with error ");
    }
}

void UDPClient::sendto(char* request, size_t length, sockaddr_in addr)
{
    try
    {
        int sendResult = ::sendto(_clientSocket, request, length, 0, (SOCKADDR*)&addr, sizeof(addr));
        if (sendResult == SOCKET_ERROR)
        {
            throw SocketException("send failed: ");
        }
    }
    catch (...)
    {
        cout << "ERROR S" << endl;
    }
}


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