Mac C ++ Broadcast - >多个网络接口

时间:2016-02-18 10:34:32

标签: macos c++11 udp broadcast network-interface

我的Mac上有一个广播节目,一切正常,但如果我有一个以上的网络界面,他没有收到任何东西。

所以我现在想做的是:

检查mac上激活的网络接口

向每个活动界面发送广播(所以我必须选择我想要使用的接口)

收到答案(如果有的话:))

有趣: 广播客户端在我的WLAN上(设备之间有路由器),我的局域网上有正常的互联网连接。如果我在系统配置中停用LAN,他也没有找到我的其他设备,但是如果我拉电缆他找到了另一台设备......所以也许我没有看到哪个接口是激活并查看连接的接口。

你有这些tipps或良好的谷歌关键字吗?

1 个答案:

答案 0 :(得分:2)

很久以前,如果有人找到我的帖子,这是我的解决方案:

#include <stdint.h>
static uint32 Inet_AtoN(const char * buf)
{
    // net_server inexplicably doesn't have this function; so I'll just fake it
    uint32 ret = 0;
    int shift = 24;  // fill out the MSB first
    bool startQuad = true;
    while ((shift >= 0) && (*buf))
    {
        if (startQuad)
        {
            unsigned char quad = (unsigned char)atoi(buf);
            ret |= (((uint32)quad) << shift);
            shift -= 8;
        }
        startQuad = (*buf == '.');
        buf++;
    }
    return ret;
}

int Broadcast::BroadcastToAllInterfaces()
{
    DEBUG_LOG(1,"Start Broadcast To All Interfaces", "DEv1");
    globalDatabase->SetInBroadcast();
    moreThenOne = 0;    
#if defined(USE_GETIFADDRS)
    struct ifaddrs * ifap;
    if (getifaddrs(&ifap) == 0)
    {
        struct ifaddrs * p = ifap;
        while (p)
        {
            uint32 ifaAddr = SockAddrToUint32(p->ifa_addr);
            uint32 maskAddr = SockAddrToUint32(p->ifa_netmask);
            uint32 dstAddr = SockAddrToUint32(p->ifa_dstaddr);
            if (ifaAddr > 0)
            {
                char ifaAddrStr[32];  Inet_NtoA(ifaAddr, ifaAddrStr);
                char maskAddrStr[32]; Inet_NtoA(maskAddr, maskAddrStr);
                char dstAddrStr[32];  Inet_NtoA(dstAddr, dstAddrStr);
                std::stringstream addr, descss;
                std::string addrs, descs;
                addr << dstAddrStr;
                descss << p->ifa_name;
                descss >> descs;
                addr >> addrs;
                DoABroadcast(dstAddr);
            }
            p = p->ifa_next;
        }
        freeifaddrs(ifap);
    }
#elif defined(WIN32)
    // Windows XP style implementation

    // Adapted from example code at http://msdn2.microsoft.com/en-us/library/aa365917.aspx
    // Now get Windows' IPv4 addresses table.  Once again, we gotta call GetIpAddrTable()
    // multiple times in order to deal with potential race conditions properly.
    MIB_IPADDRTABLE * ipTable = NULL;       
    {
        ULONG bufLen = 0;                   
        for (int i = 0; i<5; i++)
        {
            DWORD ipRet = GetIpAddrTable(ipTable, &bufLen, false);      
            if (ipRet == ERROR_INSUFFICIENT_BUFFER)
            {
                free(ipTable);                                           // in case we had previously allocated it      STILL_RUN
                ipTable = (MIB_IPADDRTABLE *)malloc(bufLen);            
            }   
            else if (ipRet == NO_ERROR) break;
            else
            {
                free(ipTable);          
                ipTable = NULL;         
                break;
            }
        }
    }

    if (ipTable)
    {
        IP_ADAPTER_INFO * pAdapterInfo = NULL;  
        {
            ULONG bufLen = 0;           
            for (int i = 0; i<5; i++)
            {
                DWORD apRet = GetAdaptersInfo(pAdapterInfo, &bufLen);   
                if (apRet == ERROR_BUFFER_OVERFLOW)
                {
                    free(pAdapterInfo);   // in case we had previously allocated it
                    pAdapterInfo = (IP_ADAPTER_INFO *)malloc(bufLen); 
                }
                else if (apRet == ERROR_SUCCESS) break;
                else
                {
                    free(pAdapterInfo);     
                    pAdapterInfo = NULL;    
                    break;
                }
            }
        }

        for (DWORD i = 0; i<ipTable->dwNumEntries; i++)
        {
            const MIB_IPADDRROW & row = ipTable->table[i];      

            // Now lookup the appropriate adaptor-name in the pAdaptorInfos, if we can find it
            const char * name = NULL;                           
            const char * desc = NULL;                           
            if (pAdapterInfo)   
            {
                IP_ADAPTER_INFO * next = pAdapterInfo;          
                while ((next) && (name == NULL))            
                {
                    IP_ADDR_STRING * ipAddr = &next->IpAddressList;     
                    while (ipAddr)
                    {
                        if (Inet_AtoN(ipAddr->IpAddress.String) == ntohl(row.dwAddr))
                        {
                            name = next->AdapterName;           
                            desc = next->Description;           
                            break;
                        }
                        ipAddr = ipAddr->Next;                  
                    }
                    next = next->Next;                          
                }
            }
            char buf[128];                          
            int setUnnamed = 0;                     
            if (name == NULL)
            {
                sprintf(buf, "unnamed");            
                name = buf;                         
                setUnnamed = 1;                     
            }

            uint32 ipAddr = ntohl(row.dwAddr);      
            uint32 netmask = ntohl(row.dwMask);     
            uint32 baddr = ipAddr & netmask;        
            if (row.dwBCastAddr) baddr |= ~netmask; 

            char ifaAddrStr[32];  Inet_NtoA(ipAddr, ifaAddrStr);    
            char maskAddrStr[32]; Inet_NtoA(netmask, maskAddrStr);  
            char dstAddrStr[32];  Inet_NtoA(baddr, dstAddrStr);     
            std::stringstream addr, descss;         
            std::string addrs, descs;               
            if (setUnnamed == 0)
            {
                addr << dstAddrStr;                 
                descss << desc;                     
                descss >> descs;                    
                addr >> addrs;                      
                DoABroadcast(baddr);                
            }
        }
        free(pAdapterInfo);                         
        free(ipTable);                              
    }
#else
    // Dunno what we're running on here!
#  error "Don't know how to implement PrintNetworkInterfaceInfos() on this OS!"
#endif
    globalDatabase->SetLeaveBroadcast();
return 1;
}



int Broadcast::DoABroadcast(uint32 broadAddr)
{
    int askSinlen = sizeof(struct sockaddr_in);     
    int askBuflen = MAXBUF;                         
    int message;                                    
    char buf[512];                                  
    int status;                                     
    char askBuffer[MAXBUF];                         
    struct sockaddr_in sock_in, client_adress, client_adress2;      

#ifdef __APPLE__

    socklen_t clientLength;                         
    int askYes = 1;                                 

#else

    char askYes = 1;                                
    int clientLength;                               
    WSADATA w;
    int result = WSAStartup(MAKEWORD(2, 2), &w);

#endif

    int recSocket = socket(AF_INET, SOCK_DGRAM, 0); 

    if (recSocket <0)
    {
#ifdef __APPLE__
        close(recSocket);   
#else
        closesocket(recSocket); 
#endif
        inBroadcast = false;
        return 10;
    }
    sock_in.sin_addr.s_addr = htonl(INADDR_ANY);    
    sock_in.sin_port = htons(4028);                 
    sock_in.sin_family = PF_INET;                   

    client_adress.sin_family = PF_INET;             
    client_adress.sin_port = htons(4029);           
    client_adress.sin_addr.s_addr = htonl(broadAddr);   

    askSinlen = sizeof(sock_in);                    
    client_adress2.sin_family = AF_INET;            
    client_adress2.sin_port = htons(4028);          
    client_adress2.sin_addr.s_addr = htonl(0xc0a8b2ff);

    status = setsockopt(recSocket, SOL_SOCKET, SO_BROADCAST, &askYes, sizeof(askYes));
    if (status < 0)
    {

#ifdef __APPLE__
        close(recSocket);
#else
        closesocket(recSocket);

#endif
        inBroadcast = false;
        return 10;
    }

    status = bind(recSocket, (struct sockaddr *)&sock_in, askSinlen);
    if (status < 0)
    {

#ifdef __APPLE__
        close(recSocket);   
#else
        closesocket(recSocket); 

#endif
        inBroadcast = false;
        return 10;
    }


    askBuflen = sprintf(askBuffer, "Ciao Mac ist hier");    
    status = sendto(recSocket, askBuffer, askBuflen, 0, (struct sockaddr *)&client_adress, sizeof(client_adress));
    fd_set fds;                 
    struct timeval tv;          

    tv.tv_sec = 2;              
    tv.tv_usec = 0;             
    FD_ZERO(&fds);              
    FD_SET(recSocket, &fds);    
    int ret;                    
    if ((ret = select(recSocket +1, &fds, NULL, NULL, &tv)) > 0)
    {
        int e = 0;              
        while ((ret = select(recSocket + 1, &fds, NULL, NULL, &tv)) > 0)
        {
            clientLength = sizeof(client_adress2);  
                message = recvfrom(recSocket, buf, sizeof(buf), 0, (struct sockaddr*) &client_adress2, &clientLength);  
            if (message == -1)
            {
#ifdef __APPLE__
                    close(recSocket);   
#else
                    closesocket(recSocket); 
#endif
                inBroadcast = false;
                return -5;
            }
            else
            {

                std::string hereisyourbroadcast(buf);               

            }

        }


    }
    else
    {

#ifdef __APPLE__
            close(recSocket);       
#else
            closesocket(recSocket);     
#endif
        inBroadcast = false;
        return -6;
    }

#ifdef __APPLE__
    close(recSocket);               
#else 
    closesocket(recSocket);         
#endif
    inBroadcast = false;
    return 1;
}