GCDAsyncUdpSocket и многоадресная отправка и получение

В первом подходе я создаю клиент-серверное приложение на основе sampleProject, которое отправить некоторые данные на сервер.

Legend:
sender
    address = reciver ip
    port = reciver port
reciver
    address = null since he is listening
    port = in my case 55555

Рабочий код

пропуск проверки ошибок преднамерен только по публичным причинам

Отправитель

-(id*)initForSender:(NSString*)address port:(int)port
 {
   self = [super init];
   if (self) {
        _port = port;
        _address = address;
        tag = 0;
        _udpSocket = [[GCDAsyncUdpSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_main_queue()];

        [_udpSocket bindToPort:0 error:&error];
        [_udpSocket beginReceiving:&error];

      return self;
    }
}

-(void)send:(NSData*)data{
     [_udpSocket sendData:data toHost:_address port:_port withTimeout:-1 tag:tag];
     tag++;
}

Приемник/слушатель

-(id*)initForReceiver:(NSString*)address port:(int)port
{
   self = [super init];
   if (self) {
        _port = port;
        _udpSocket = [[GCDAsyncUdpSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_main_queue()];
        NSError *error = nil;

       [_udpSocket bindToPort:0 error:&error];
       [_udpSocket beginReceiving:&error];
    }
    return self;
}

- (void)udpSocket:(GCDAsyncUdpSocket *)sock didReceiveData:(NSData *)data
      fromAddress:(NSData *)address
withFilterContext:(id)filterContext
{
    //Do something with receive data
}

Мультикаст

Но тогда мне нужен клиент, который будет отправлять многим получателям. Насколько я знаю, отправитель или слушатель должны использовать [GCDAsyncUdpSocket joinMulticastGroup: error];. Я пробежался по stackoverflow, дяде Google и CococaAsyncSocket (где нет ни слова о udp), сопоставил собранную информацию и придумал этот код. Я совершенно уверен, что это не работает, но я понятия не имею, почему.

Legend:
sender
    address = sender ip
    port = sender port in my case 55555
reciver
    address = sender ip
    port = sender port in my case 55555

Не рабочий код

-(id*)initForSender:(NSString*)address port:(int)port
{
    self = [super init];
    if (self) {
        _port = port;
        _address = address;
        _udpSocket = [[GCDAsyncUdpSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_main_queue()];
        NSError *error = nil;

        [_udpSocket bindToPort:_port error:&error];
        [_udpSocket joinMulticastGroup:_address error:&error];
        [_udpSocket enableBroadcast:YES error:&error];

    }
    return self;
}

-(void)send:(NSData*)data{
     [_udpSocket sendData:data toHost:_address port:_port withTimeout:-1 tag:tag];
     tag++;
}

Приемник/слушатель

-(id*)initForReceiver:(NSString*)address port:(int)port
{
    self = [super init];
    if (self) {
        _port = port;
        _address = address;
        _udpSocket = [[GCDAsyncUdpSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_main_queue()];
         NSError *error = nil;

        [_udpSocket bindToPort:_port error:&error];
        [_udpSocket joinMulticastGroup:_address error:&error];
        [_udpSocket beginReceiving:&error])

    }
    return self;
}

- (void)udpSocket:(GCDAsyncUdpSocket *)sock didReceiveData:(NSData *)data
      fromAddress:(NSData *)address
withFilterContext:(id)filterContext
{
   //Do something with receive data
}

ОБНОВИТЬ:

Оказывается, когда я использую какой-то неиспользуемый IP-адрес как address, например, @"224.0.1.1", это работает, но это немного странно. Я делаю это правильно?


person Błażej    schedule 09.08.2013    source источник
comment
Вы сделали довольно много ошибок. Вот пример клиента и сервера UDP от автора этой библиотеки. github.com/robbiehanson/CocoaAsyncSocket/tree/master/GCD/Xcode Удачи!   -  person user523234    schedule 09.08.2013
comment
@ user523234: Я обновляю свой вопрос. Заполните его дополнительными данными :). Я знаком с примером, но udpEchoServer и udpEchoClient — это то, что я уже сделал. Теперь мне нужен мультикаст.   -  person Błażej    schedule 09.08.2013


Ответы (1)


  1. Многоадресные адреса — это специальные зарезервированные адреса для многоадресной рассылки. Когда хост отправляет данные на многоадресный адрес (группу), все хосты, присоединившиеся к этой группе, получат данные.

  2. Любой хост, который хочет получать данные из группы многоадресной рассылки, должен присоединиться к этой группе. Три шага для GCDAsyncUdpSocket: (обратите внимание, что комбинация группового адреса и группового порта должна быть уникальной для выбранной группы многоадресной рассылки)

    [_udpSocket bindToPort:_port error:&error];
    [_udpSocket joinMulticastGroup:_address error:&error];
    [_udpSocket beginReceiving:&error])
    
  3. Для отправителя вам не нужны эти две строки, как у вас.

    [_udpSocket bindToPort:0 error:&error];  //bindToPort:0 is same as auto-select sender port by default.
    [_udpSocket beginReceiving:&error];   //if you don't want to received, no need for this.
    

Используйте 239.0.0.0-239.255.255.255 для вашей частной локальной сети. Избегайте 224 . Подробнее можно прочитать по ссылке выше.

person user523234    schedule 10.08.2013
comment
Итак, моя проблема была в плохом адресе. хД - person Błażej; 13.08.2013