导航:[首页]->[network]->[广播数据到所有网口]
#ifdef WIN32
#define _CRT_SECURE_NO_WARNINGS
#include <winsock2.h>
#include <ws2tcpip.h>
#include <Iphlpapi.h>
#else
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netpacket/packet.h>
#include <netinet/in.h>
#include <linux/if_ether.h>
#include <ifaddrs.h>
#include <unistd.h>

#endif
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <assert.h>

#ifdef WIN32
#pragma comment(lib,"Ws2_32.lib")
#pragma comment(lib,"Iphlpapi.lib")
typedef SOCKET socket_t;
typedef u_long IP_t;
#else
typedef int socket_t;
typedef in_addr_t IP_t;
#define  INVALID_SOCKET  -1
#define closesocket close
#endif

#include <iostream>
#include <vector>
typedef std::vector<IP_t> IPVector;
typedef IPVector::const_iterator IPIter;


#ifdef WIN32
bool GetIP(IPVector& ips)
{
    char* buf_ = new char[sizeof(IP_ADAPTER_INFO)];
    PIP_ADAPTER_INFO pIpAdapterInfo = reinterpret_cast<IP_ADAPTER_INFO*>(buf_);
    unsigned long stSize = sizeof(IP_ADAPTER_INFO);
    int nRel = GetAdaptersInfo(pIpAdapterInfo,&stSize);
    // 处理Buf内存不足的情况
    if (ERROR_BUFFER_OVERFLOW == nRel)
    {
    delete [] pIpAdapterInfo;
    buf_ = new char[stSize];
    pIpAdapterInfo = reinterpret_cast<IP_ADAPTER_INFO*>(buf_);
    nRel=GetAdaptersInfo(pIpAdapterInfo,&stSize);    
    }
    if (ERROR_SUCCESS != nRel)
    {
    delete [] buf_;
    return false;
    }
    while (pIpAdapterInfo)
    {
    // 过滤以太网
    if(pIpAdapterInfo->Type == MIB_IF_TYPE_ETHERNET)
    {
        pIpAdapterInfo = pIpAdapterInfo->Next;
        continue;
    }
    std::cout << "name:" << pIpAdapterInfo->Description << std::endl;
    std::cout << "description:" << pIpAdapterInfo->AdapterName << std::endl;

    // 一个网卡可能有多个IP地址
    IP_ADDR_STRING *pIpAddrString =&(pIpAdapterInfo->IpAddressList);
    do
    {
        IP_t ip_,mask_,broadcastip_;
        if(inet_pton(AF_INET,pIpAddrString->IpAddress.String,&ip_) != 1 ||
                inet_pton(AF_INET,pIpAddrString->IpMask.String,&mask_) != 1 ||
                ip_ == 0 ||
                mask_ == 0)
        {
            pIpAddrString=pIpAddrString->Next;
            continue;
        }
        broadcastip_ = ip_ | (~mask_);

        char ipbuf_[64];
        inet_ntop(AF_INET,&broadcastip_,ipbuf_,sizeof(ipbuf_));

        std::cout << "ip:" << pIpAddrString->IpAddress.String << std::endl;
        std::cout << "mask:" << pIpAddrString->IpMask.String << std::endl;
        std::cout << "gateway:" << pIpAdapterInfo->GatewayList.IpAddress.String << std::endl;
        std::cout << "broadcast:" << ipbuf_ << std::endl;

        ips.push_back(broadcastip_);

        pIpAddrString=pIpAddrString->Next;
    } while (pIpAddrString);

    pIpAdapterInfo = pIpAdapterInfo->Next;
    }
    delete [] buf_;
    return true;
}
#else
bool GetIP(IPVector& ips)
{
    struct ifaddrs * ifaddr_ = NULL;
    if(!!getifaddrs(&ifaddr_))
    {
    printf("getifaddrs error '%d|%s'\n",errno,strerror(errno));
    return -1;
    }

    while (ifaddr_ != NULL) 
    {
    if (ifaddr_->ifa_addr &&
            ifaddr_->ifa_name &&
            ifaddr_->ifa_addr->sa_family == AF_INET) 
    {
        struct sockaddr_in* addrptr_ =
            (struct sockaddr_in*)(ifaddr_->ifa_addr);
        struct sockaddr_in* maskptr_ =
            (struct sockaddr_in*)(ifaddr_->ifa_netmask);
        printf("eth '%s' with ip '%s' \n",
                ifaddr_->ifa_name,
                inet_ntoa(addrptr_->sin_addr));
        printf("eth '%s' with mask '%s' \n",
                ifaddr_->ifa_name,
                inet_ntoa(maskptr_->sin_addr));

        IP_t broadcastip_ = addrptr_->sin_addr.s_addr  | (~(maskptr_->sin_addr.s_addr));

        char ipbuf_[64];
        inet_ntop(AF_INET,&broadcastip_,ipbuf_,sizeof(ipbuf_));
        printf("eth '%s' with broadcast ip '%s' \n",
                ifaddr_->ifa_name,
                ipbuf_);
        ips.push_back(broadcastip_);
    }
    ifaddr_ = ifaddr_->ifa_next;
    }
    freeifaddrs(ifaddr_);
}
#endif

int main(int argc,const char** argv)
{

#ifdef WIN32
    WSADATA wsaData = {0};
    WSAStartup(MAKEWORD(2, 2), &wsaData);
#endif

    IPVector ips_;
    if(!GetIP(ips_))
    {
    return 1;
    }

    return 0;
    socket_t fd_ = socket(AF_INET,SOCK_DGRAM,0);
    if(fd_ == INVALID_SOCKET)
    {
    printf("socket error '%d|%s'\n",errno,strerror(errno));
    return -1;
    }

    int flag_ = 1;
    if(setsockopt(fd_, SOL_SOCKET,
            SO_BROADCAST, (char*)&flag_, sizeof(flag_)) < 0) {
    closesocket(fd_);
    return -1;
    }

    const char* msg_ = "test";
    struct sockaddr_in addr_;
    addr_.sin_family = AF_INET;
    addr_.sin_port = htons(12345);
    for(IPIter iter_ = ips_.begin();
        iter_ != ips_.end();
        ++ iter_)
    {
    addr_.sin_addr.s_addr = *iter_;
    if(sendto(fd_,msg_,strlen(msg_)+1,
                0,
                (struct sockaddr*)&addr_,
                sizeof(addr_)) < 0)
    {
#ifdef WIN32
        printf("socket error '%d'\n",WSAGetLastError(errno));
#else
        printf("socket error '%d|%s'\n",errno,strerror(errno));
#endif
    }
    }
    return 0;
}

参考

  1. http://www.linuxsir.org/bbs/thread16872.html
  2. http://qjw.qiujinwu.com/blog/2013/07/17/socket_sample/