通过所有可用的网络接口使用GCDAsyncUdpSocket进行UDP广播 [英] UDP broadcast using GCDAsyncUdpSocket through all available Network Interfaces

查看:213
本文介绍了通过所有可用的网络接口使用GCDAsyncUdpSocket进行UDP广播的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am using GCDAsyncUdpSocket for broadcasting UDP packets for searching my NAS devices.

下面是用于发送和接收UDP数据包的代码段

Below is the code snippet for sending and receiving UDP packets

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等).

The above code can send packets through only single Network interface i.e either Wifi or Ethernet or Thunderbolt, the thing is i want to broadcast through all of the available Network Interfaces. (Ethernet, WiFi, Thunderbolt etc.).

我是否可以同时使用同一端口通过所有可用的网络接口(以太网,WiFi,Thunderbolt等)进行广播.

Is there any way i can broadcast via all the available Network Interfaces (Ethernet, WiFi, Thunderbolt etc.) at the same time and using the same port.

感谢您的帮助,谢谢.

推荐答案

Ph!经过大量的Google搜索和试用,我终于找到了解决方案.错误方法.解决方案在这里.

Phew!! I figured out a solution after lot of googling and trial & error methods. Here goes the solution.

  1. 首先使用以下功能枚举所有可用的网络接口.

  1. First enumerate all the available Network interfaces using the below function.

- (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.

I have created InterfaceModel which stores the Interface Name and its Address.

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

Step 2: Create a Socket for each Interface

    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步:将所有已创建的套接字存储在一个数组中,并通过每个套接字进行广播,如下所示,但是在广播之前,我们需要创建一个侦听器套接字以接收响应数据包.

Step 3: Store all the created sockets in a array and broadcast through each of them as follows, but before broadcasting, we need to create a listener socket to receive the response packets.

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

这篇关于通过所有可用的网络接口使用GCDAsyncUdpSocket进行UDP广播的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆