UDP广播在机器上与多个网络适配器在Windows与本机c++

UDP broadcast on machine with multiple network adapters on Windows with native C++

本文关键字:网络适配器 Windows 本机 c++ 机器 UDP 广播      更新时间:2023-10-16

我需要在Windows机器上使用本地c++代码进行UDP广播(我认为理想情况下应该是多播)。

目前,我正在套接字上设置SO_BROADCAST套接字选项以允许广播,然后发送到INADDR_BROADCAST地址(255.255.255.255)。这在具有多个网络适配器的机器上不可靠地工作。

我一直在四处搜索,在Stack Overflow上发现了大量关于这个的问题。据我所知,最好的方法似乎是找出每个网络适配器的广播IP,然后循环发送到每个网络适配器的IP。

因此,例如,如果我的机器有一个10.0.0的网络适配器。另一个IP地址为192.168.1. x。x,然后我需要发送消息到10.0.0.255和192.168.1.255。

尽管我浏览了所有的问题/答案,但我还是不能把这些点联系起来,得到上面的地址列表。

谁能给我指个正确的方向?例如,我找到了一些使用GetAdaptersAddresses枚举IP地址的示例代码,但我不知道从哪里可以获得每个地址的子网掩码。没有子网掩码,我无法确定广播地址。我需要IP地址列表,以及每个IP地址的子网掩码,这样我就可以形成要发送到的广播地址列表。

API调用GetAdaptersInfo为每个网络适配器填充一个IP_ADAPTER_INFO结构体。根据文档,掩码在地址列表中提供:

http://msdn.microsoft.com/en-us/library/windows/desktop/aa366062 (v = vs.85) . aspx

你可以计算广播地址一旦你有IP地址和掩码:

根据ip和子网掩码计算广播地址

RichardBrock的答案是正确的,GetAdaptersInfo给出了所需的信息。下面的一些代码更具体地展示了如何做到这一点。请注意,这段代码使用了MFC和字符串转换宏STR_A2T,它只是将char*字符串转换为wchar_t*字符串,因为该项目是为Unicode构建的。结果是一个字符串数组,其中每个字符串都是一个广播IP。然后我们循环遍历它们并发送给每一个。

CStringArray baList;
baList.RemoveAll();
ULONG bufSz = 0;
if (GetAdaptersInfo(NULL,&bufSz) == ERROR_BUFFER_OVERFLOW)
{
    vector<BYTE> buf;
    buf.resize(bufSz,0);
    if (GetAdaptersInfo((IP_ADAPTER_INFO*)&buf[0],&bufSz) == ERROR_SUCCESS)
    {
        IP_ADAPTER_INFO* pAdapterInfo = (IP_ADAPTER_INFO*)&buf[0];
        for(; pAdapterInfo != NULL; pAdapterInfo = pAdapterInfo->Next)
        {
            unsigned long ip = inet_addr(pAdapterInfo->IpAddressList.IpAddress.String);
            unsigned long mask = inet_addr(pAdapterInfo->IpAddressList.IpMask.String);
            unsigned long bcip = ip | ~mask;
            struct in_addr ia;
            ia.S_un.S_addr = bcip;
            CString broadcastAddr;
            STR_A2T(inet_ntoa(ia),broadcastAddr);
            baList.Add(broadcastAddr);
        }
    }
}