Не удалось получить ответ об отправленных пакетах UDP с помощью GCDAsyncSocket

Я делаю приложение для отправки UDP пакеты для того, чтобы включить LED bulb, Я смог выполнить все действия при подключении к Ad-hoc созданный Wifi bridge,

Теперь я хочу настроить Wifi bridge так что он может подключиться к моему основному маршрутизатору. У меня есть AT-команда для выполнения этой процедуры, но я не могу получить ответ от Wifi bridge для команд, которые я посылаю ему.

Процедура выглядит следующим образом:

  • Шаг 1. Отправьте UDP-сообщение на широковещательный IP-адрес локальной сети "10.10.100.255" и порт 48899 => "Link_Wi-Fi".
    Все Wifi мосты в локальной сети ответят своими подробностями. Ответ "10.10.100.254, ACCF232483E8"

  • Шаг 2: (необязательно для изменения настроек на мосту wifi): Затем отправьте "+ok" на мост LimitlessLED Wifi. Отправьте UDP-сообщение на IP-адрес ответа, полученный на шаге 1 "10.10.100.254" => "+ok"

  • Шаг 3: (необязательно для изменения настроек на мосту Wi-Fi): После этого вы можете отправлять AT-команды (заканчивающиеся на \r\n) в модуль.

Код для отправки пакетов UDP выглядит следующим образом

-(void)configureWifi{

    counter++;
    NSString *host = @"10.10.100.255";
    if ([host length] == 0)
    {
        [self logError:@"Address required"];
        return;
    }

    int port = 48899; //[portField.text intValue];
    if (port <= 0 || port > 65535)
    {
        [self logError:@"Valid port required"];
        return;
    }
    NSString *msg = @"Link_Wi-Fi";
    NSData *data = [msg dataUsingEncoding:NSUTF8StringEncoding];
    NSLog(@"the message sent is %@", data);
    [udpSocket sendData:data toHost:host port:port withTimeout:-1 tag:tag];

}

Теперь, чтобы настроить сокет и получить данные, я использую эти два метода делегата:

 - (void)setupSocket
{
    // Setup our socket.
    // The socket will invoke our delegate methods using the usual delegate paradigm.
    // However, it will invoke the delegate methods on a specified GCD delegate dispatch queue.
    // 
    // Now we can configure the delegate dispatch queues however we want.
    // We could simply use the main dispatc queue, so the delegate methods are invoked on the main thread.
    // Or we could use a dedicated dispatch queue, which could be helpful if we were doing a lot of processing.
    // 
    // The best approach for your application will depend upon convenience, requirements and performance.
    // 
    // For this simple example, we're just going to use the main thread.

    udpSocket = [[GCDAsyncUdpSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_main_queue()];

    NSError *error = nil;

    if (![udpSocket bindToPort:0 error:&error])
    {
        [self logError:FORMAT(@"Error binding: %@", error)];
        return;
    }
    if (![udpSocket beginReceiving:&error])
    {
        [self logError:FORMAT(@"Error receiving: %@", error)];
        return;
    }

    [self logInfo:@"Ready"];
}

и для получения данных это метод, который вызывается после отправки пакетов UDP. Это метод делегата GCDAsyncUdpSocket класс, который я использовал в своем проекте для отправки и получения пакетов UDP.

- (void)udpSocket:(GCDAsyncUdpSocket *)sock didReceiveData:(NSData *)data
                                               fromAddress:(NSData *)address
                                         withFilterContext:(id)filterContext
{
    NSString *msg = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
    if (msg)
    {
        [self logMessage:FORMAT(@"RECV: %@", msg)];
    }
    else
    {
        NSString *host = nil;
        uint16_t port = 0;
        [GCDAsyncUdpSocket getHost:&host port:&port fromAddress:address];

        [self logInfo:FORMAT(@"RECV: Unknown message from: %@:%hu", host, port)];
    }
}

Как только я смогу получить ответ, я смогу отправить следующие AT-команды для настройки Моста.

Благодарю. Любая помощь будет оценена.

2 ответа

Вот шаги по устранению неполадок, которые я рекомендую вам использовать:

1- Я предполагаю, что вы используете ARC поэтому убедитесь, что ваш udpSocket Переменная имеет сильную ссылку на всю асинхронную связь. Если он освобождается, то это может объяснить отсутствие обратного вызова.

2. Убедитесь, что общение действительно происходит так, как вы думаете. Используйте программное обеспечение, такое как Wireshark захватить пакеты, которыми обмениваются в сети. Это должно позволить вам подтвердить, что ваши пакеты действительно отправляются после вызова sendData: и это также позволит вам подтвердить, получаете ли вы ответ обратно или нет.

3- Убедитесь, что вы используете GCDAsyncUdpSocket должным образом. Учитывая, что вы хотите передать сообщение, вы не должны звонить bindToPort:error: в вашем setupSocket метод. Вместо этого вы должны звонить enableBroadcast:error:, Учитывая, что вы также хотите получать пакеты после трансляции, вы должны использовать connectToHost:onPort:error: метод для изменения состояния сокета, чтобы обеспечить двунаправленную связь. После этого вы можете заменить использование sendData:toHost:port:withTimeout:tag: от sendData:withTimeout:tag:, Наконец, вы можете позвонить beginReceiving: так что делегат вызывается для любых входящих пакетов.

4. Если это все еще не помогает вам, я рекомендую вам внимательно прочитать документацию GCDAsyncUdpSocket, которая очень хорошо документирована.

Вы можете решить проблему, используя Wireshark или любой инструмент захвата сети. Мы привыкли работать в подобных проектах, где мы широко использовали Wireshark. Если пакет достиг устройства (Z-Wave), он отправит какой-нибудь Ack. это поможет убедиться, что пакеты выходят.

Другие вопросы по тегам