Подтвердить что ты не робот

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

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

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

Процедура такова: -

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

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

  • Шаг 3: (необязательно для изменения настроек на wifi-мосте): после этого вы можете отправить 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-команды, чтобы настроить мост.

Спасибо. Любая помощь будет оценена.

4b9b3361

Ответ 1

Ниже приведены действия по устранению неполадок, которые я рекомендую использовать:

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, которая хорошо документирована.

Ответ 2

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