代码之家  ›  专栏  ›  技术社区  ›  TheRealLife

Mac C++广播->多个网络接口

  •  1
  • TheRealLife  · 技术社区  · 8 年前

    我的mac上有一个广播节目,一切都很好,但如果我有一个以上的网络接口,他什么都没收到。

    所以我现在想做的是:

    检查mac上哪些网络接口处于活动状态

    向每个activ接口发送广播(因此我必须选择要使用的接口)

    接收答案(如果有:)

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

    你有什么小贴士或好的谷歌关键词给我吗?

    1 回复  |  直到 8 年前
        1
  •  2
  •   TheRealLife    7 年前

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

    #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;
    }