Невозможно получить широковещательные сообщения UDP - PullRequest
0 голосов
/ 12 декабря 2018

Я пытаюсь собрать монитор UDP.Я думал, что это будет просто, но все, что я пробовал, не сработало.

В настоящее время я работаю с примером кода Microsoft .Из-за моих прошлых неудачных попыток я просто скопировал код веб-сайта и изменил номер порта (см. Ниже), но я все еще не могу получить дейтаграммы.

#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>

int iResult = 0;
WSADATA wsaData;
SOCKET RecvSocket;
sockaddr_in RecvAddr;
unsigned short Port = 18190;

char RecvBuf[1024];
int BufLen = 1024;
sockaddr_in SenderAddr;
int SenderAddrSize = sizeof (SenderAddr);

//-----------------------------------------------
// Initialize Winsock
iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != NO_ERROR) {
    wprintf(L"WSAStartup failed with error %d\n", iResult);
    return 1;
}
//-----------------------------------------------
// Create a receiver socket to receive datagrams
RecvSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (RecvSocket == INVALID_SOCKET) {
    wprintf(L"socket failed with error %d\n", WSAGetLastError());
    return 1;
}
//-----------------------------------------------
// Bind the socket to any address and the specified port.
RecvAddr.sin_family = AF_INET;
RecvAddr.sin_port = htons(Port);
RecvAddr.sin_addr.s_addr = htonl(INADDR_ANY);

iResult = bind(RecvSocket, (SOCKADDR *) &RecvAddr, sizeof (RecvAddr));
if (iResult != 0) {
    wprintf(L"bind failed with error %d\n", WSAGetLastError());
    return 1;
}
//-----------------------------------------------
// Call the recvfrom function to receive datagrams
// on the bound socket.
wprintf(L"Receiving datagrams...\n");
iResult = recvfrom(RecvSocket,
                   RecvBuf, BufLen, 0, (SOCKADDR *) &SenderAddr, &SenderAddrSize);
if (iResult == SOCKET_ERROR) {
    wprintf(L"recvfrom failed with error %d\n", WSAGetLastError());
}

//-----------------------------------------------
// Close the socket when finished receiving datagrams
wprintf(L"Finished receiving. Closing socket.\n");
iResult = closesocket(RecvSocket);
if (iResult == SOCKET_ERROR) {
    wprintf(L"closesocket failed with error %d\n", WSAGetLastError());
    return 1;
}

//-----------------------------------------------
// Clean up and exit.
wprintf(L"Exiting.\n");
WSACleanup();

Используя Wireshark, я вижу сообщения, поступающие вкак и ожидалось (исходный IP-адрес 10.1.1.150) Wireshark capture

Я добавил правила в брандмауэр Windows 10, чтобы убедиться, что порт 18190 открыт и не будет отклонять приходящие сообщениявход или выход через этот порт.

Многие веб-сайты утверждают, что для клиентов не следует связывать сокет, но если я не связываю сокет, то recvfrom() немедленно возвращает значение -1 и ошибку WSAEINVAL, в котором говорится, что «указан неверный аргумент».

Примечание. Я хочу использовать recvfrom() вместо recv(), поскольку мне нужна информация об адресе отправителя.

МожетКто-нибудь, помогите мне понять, почему этот код не получает транслируемые дейтаграммы UDP?

Обновление

Я пытался отправить сообщение через sendto() перед вызовом recvfrom().Wireshark показывает, что сообщение было отправлено 10.1.1.150, но recvfrom() по-прежнему ничего не получает (т. Е. Просто блокирует навсегда).

Обновление 2

Используя приведенный выше код, если я установлю на компьютере статический IP-адрес 10.1.1.255, я смогу получать пакеты.Это говорит мне о том, что код может принимать пакеты, но все же не объясняет, почему я не могу получать широковещательные пакеты.

1 Ответ

0 голосов
/ 14 декабря 2018

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

Моя маска подсети по умолчанию была 255.0.0.0, что неверно для получения широковещательного пакета.Изменение маски подсети на 255.255.255.0 позволяет коду получать широковещательные пакеты.

...