zoukankan      html  css  js  c++  java
  • 网络编程之广播和IP多播

    一.广播

    1.接收

    void main()
    {
        SOCKET s = ::socket(AF_INET, SOCK_DGRAM, 0);
    
        // 首先要绑定一个本地地址,指明广播端口号
        SOCKADDR_IN sin;
        sin.sin_family = AF_INET;
        sin.sin_addr.S_un.S_addr = INADDR_ANY;    
        sin.sin_port = ::ntohs(4567);
        if(::bind(s, (sockaddr*)&sin, sizeof(sin)) == SOCKET_ERROR)
        {
            printf(" bind() failed \n");
            return;
        }
    
        // 接收广播
        printf(" 开始在4567端口接收广播数据... \n\n");
        SOCKADDR_IN addrRemote;    
        int nLen = sizeof(addrRemote);
        char sz[256];
        while(TRUE)
        {
            int nRet = ::recvfrom(s, sz, 256, 0, (sockaddr*)&addrRemote, &nLen);
            if(nRet > 0)
            {
                sz[nRet] = '\0';
                printf(sz);
            }
        }
    }
    

    2.发送

    void main()
    {
        SOCKET s = ::socket(AF_INET, SOCK_DGRAM, 0);
        // 有效SO_BROADCAST选项
        BOOL bBroadcast = TRUE;
        ::setsockopt(s, SOL_SOCKET, SO_BROADCAST, (char*)&bBroadcast, sizeof(BOOL));
    
        // 设置广播地址,这里的广播端口号(电台)是4567
        SOCKADDR_IN bcast;
        bcast.sin_family = AF_INET;
        bcast.sin_addr.s_addr = INADDR_BROADCAST; // ::inet_addr("255.255.255.255");
        bcast.sin_port = htons(4567);
    
        // 发送广播
        printf(" 开始向4567端口发送广播数据... \n \n");
        char sz[] = "This is just a test. \r\n";
        while(TRUE)
        {
            ::sendto(s, sz, strlen(sz), 0, (sockaddr*)&bcast, sizeof(bcast));
            ::Sleep(5000);
        }
    }
    

    二.IP多播

    1.加入多播组并接收数据

    void main()
    {
        SOCKET s = ::socket(AF_INET, SOCK_DGRAM, 0);
    
        // 允许其它进程使用绑定的地址
        BOOL bReuse = TRUE;
        ::setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char*)&bReuse, sizeof(BOOL));
    
    
        // 绑定到4567端口
        sockaddr_in si;
        si.sin_family = AF_INET;
        si.sin_port = ::ntohs(4567);
        si.sin_addr.S_un.S_addr = INADDR_ANY;
        ::bind(s, (sockaddr*)&si, sizeof(si));
        
        // 加入多播组
        ip_mreq    mcast;
        mcast.imr_interface.S_un.S_addr = INADDR_ANY;
        mcast.imr_multiaddr.S_un.S_addr = ::inet_addr("234.5.6.7");  // 多播地址为234.5.6.7
        ::setsockopt(s, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char*)&mcast, sizeof(mcast));
    
    
        // 接收多播组数据
        printf(" 开始接收多播组234.5.6.7上的数据... \n");
        char buf[1280];
        int nAddrLen = sizeof(si);
        while(TRUE)
        {
            int nRet = ::recvfrom(s, buf, strlen(buf), 0, (sockaddr*)&si, &nAddrLen);
            if(nRet != SOCKET_ERROR)
            {
                buf[nRet] = '\0';
                printf(buf);
            }
            else
            {
                int n = ::WSAGetLastError();
                break;
            }
        }
    }
    

    2.发送广播

    同上

    设置SO_REUSEADDR,则允许多个进程绑定到这个端号,这样加入到同个端口的组都可以接收到数据

    三.源地址的IP多播

    即可指定接收组内特定IP地址的消息

    c#参考:http://www.cnblogs.com/xuhx/archive/2004/06/23/18150.html
    http://www.cnblogs.com/xuhx/archive/2004/06/27/18960.html

    Windows网络与通信程序设计 第5章

  • 相关阅读:
    java.util.Arrays类详解
    爬虫
    学习Spring框架(一)
    JAVA的网络编程
    Thread直接调用run()和start()方法的区别
    JDK JRE JVM 区别
    TCP , HTTP, IP
    一些常用的端口
    PATH CLASSTH JAVA_HOME
    浅谈Linux内存管理机制
  • 原文地址:https://www.cnblogs.com/Clingingboy/p/2086349.html
Copyright © 2011-2022 走看看