【问题标题】:UDP broadcast using GCDAsyncUdpSocket through all available Network Interfaces通过所有可用的网络接口使用 GCDAsyncUdpSocket 进行 UDP 广播
【发布时间】:2015-09-17 05:19:35
【问题描述】:

我正在使用 GCDAsyncUdpSocket 广播 UDP 数据包以搜索我的 NAS 设备。

下面是发送和接收UDP数据包的代码sn-p

NSString *broadCastAddress = @"255.255.255.255";
NSInteger udpPort =  8097;

GCDAsyncUdpSocket  *gcdAsyncUdpSocket = [[GCDAsyncUdpSocket alloc]  initWithDelegate:selfdelegateQueue:dispatch_get_main_queue()];
[gcdAsyncUdpSocket bindToPort:udpPort error:&error];
[gcdAsyncUdpSocket setPreferIPv4];

NSData *data = @“Hi there”; // Sample data
[gcdAsyncUdpSocket  enableBroadcast:YES error:&error];
[gcdAsyncUdpSocket  beginReceiving:&error];

[gcdAsyncUdpSocket  sendData:data toHost:broadCastAddress port:udpPort withTimeout:-1 tag:1];

上面的代码只能通过单个网络接口发送数据包,即 Wifi 或以太网或 Thunderbolt,问题是我想通过所有可用的网络接口进行广播。 (以太网、WiFi、Thunderbolt 等)。

有什么方法可以同时通过所有可用的网络接口(以太网、WiFi、Thunderbolt 等)并使用相同的端口进行广播。

任何帮助表示赞赏,在此先感谢。

【问题讨论】:

    标签: objective-c macos sockets networking gcdasyncudpsocket


    【解决方案1】:

    呸!!经过大量谷歌搜索和试错方法后,我找到了解决方案。解决方案来了。

    1. 首先使用以下函数枚举所有可用的网络接口。

      - (NSMutableArray *) enumerateAndGetDetailsOfAllNetworkInterfaces
      {
           NSMutableArray *interfaceArray = [[NSMutableArray alloc] init];
           struct ifaddrs *ifap, *ifa;
           struct sockaddr_in *sa;
           char *addr;
      
           getifaddrs (&ifap);
      
            for (ifa = ifap; ifa; ifa = ifa->ifa_next)
            {
             if (ifa->ifa_addr->sa_family==AF_INET)
              {
               QNInterfaceModel *interfaceModel = [[QNInterfaceModel alloc] init];
      
               sa = (struct sockaddr_in *) ifa->ifa_addr;
               addr = inet_ntoa(sa->sin_addr);
               printf("Interface: %s\tAddress: %s\n", ifa->ifa_name, addr);
      
               interfaceModel.interfaceName = [NSString stringWithCString:ifa->ifa_name encoding:NSUTF8StringEncoding];
               interfaceModel.interfaceIPAddress = [NSString stringWithCString:addr encoding:NSUTF8StringEncoding];
      
               [interfaceArray addObject:interfaceModel];
          }
      }
      
        freeifaddrs(ifap);
        return interfaceArray;
      }
      

    我创建了存储接口名称及其地址的 InterfaceModel。

    第 2 步:为每个接口创建一个套接字

        NSMutableArray *interfaceArray = [self enumerateAndGetDetailsOfAllNetworkInterfaces];
    
        for(QNInterfaceModel *interfaceModel in interfaceArray)
        {
           NSError *error;
    
           NSInteger udpPort =  8097;
    
           GCDAsyncUdpSocket *gcdAsyncUdpSocket = [[GCDAsyncUdpSocket alloc] initWithDelegate:self
                                                                             delegateQueue:dispatch_get_main_queue()];
           [gcdAsyncUdpSocket bindToPort:udpPort interface:interfaceModel.interfaceName error:&error];
    
           gcdAsyncUdpSocket.delegate = self;
    
           if(error == nil)
           {
             [_socketArray addObject:gcdAsyncUdpSocket];
           }
        }
    

    步骤3:将所有创建的socket存储在一个数组中,并通过每个socket进行广播,如下所示,但在广播之前,我们需要创建一个监听socket来接收响应包。

         NSError *error;
    
         NSString *broadCastString = @"255.255.255.255";
    
         NSInteger udpPort =  8097;
         GCDAsyncUdpSocket *listenerGCDAsyncUdpSocket = [[GCDAsyncUdpSocket alloc] initWithDelegate:self
                                                                      delegateQueue:dispatch_get_main_queue()];
        [listenerGCDAsyncUdpSocket bindToPort:udpPort error:&error];
        [listenerGCDAsyncUdpSocket setPreferIPv4];
        [listenerGCDAsyncUdpSocket  enableBroadcast:YES error:&error];
        [listenerGCDAsyncUdpSocket  beginReceiving:&error];
    
    
       // Send Packets through all the available Interfaces
       for(NSInteger i =0 ; i<_socketArray.count ;i++)
       {
        GCDAsyncUdpSocket *gcdAsyncUdpSocket = [_socketArray objectAtIndex:i];
        gcdAsyncUdpSocket.delegate = self;
    
        if(error)
        {
           // Error connecting
        }
        else
        {
            [gcdAsyncUdpSocket setPreferIPv4];
    
            NSData *data = @"Hi There";
    
            if (![gcdAsyncUdpSocket enableBroadcast:YES error:&error]) {
    
                QNDLog(@"Error enableBroadcast:%@",error);
                return;
            }
    
            [gcdAsyncUdpSocket  beginReceiving:&error];
    
            [gcdAsyncUdpSocket  sendData:data toHost:broadCastString port:udpPort withTimeout:-1 tag:i];
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-05-16
      • 2010-10-15
      • 1970-01-01
      • 1970-01-01
      • 2015-06-21
      • 1970-01-01
      相关资源
      最近更新 更多