ios objective-c sockets gcdasyncsocket gcdasyncudpsocket

ios - No se puede recibir la respuesta de los paquetes UDP enviados utilizando GCDAsyncSocket



objective-c sockets (2)

Estoy creando una aplicación para enviar paquetes UDP para encender una LED bulb . He podido realizar todas las acciones cuando me conecto al Ad-hoc creado por el Wifi bridge .

Ahora, quiero configurar el Wifi bridge para que pueda conectarse a mi enrutador principal. Tengo el comando AT configurado para realizar este procedimiento, pero de alguna manera no puedo recibir la respuesta del Wifi bridge para los comandos que le estoy enviando.

El procedimiento es el siguiente:-

  • Paso 1: envíe un mensaje UDP a la dirección IP de transmisión de LAN de "10.10.100.255" y el puerto de 48899 => "Link_Wi-Fi"
    Todos los puentes Wifi en la LAN responderán con sus detalles. La respuesta es "10.10.100.254, ACCF232483E8"

  • Paso 2: (opcional para cambiar la configuración en el puente wifi): luego envía "+ ok" al puente Wifi ilimitado sin límite. Envíe un mensaje UDP a la dirección IP de respuesta devuelta desde el paso 1 "10.10.100.254" => "+ ok"

  • Paso 3: (opcional para cambiar la configuración en el puente wifi): después de eso, puede enviar comandos AT (que terminan con / r / n) al módulo.

El código para enviar los paquetes UDP es el siguiente

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

Ahora, para configurar el zócalo y recibir los datos, estoy usando estos dos métodos de delegado:

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

y para recibir datos, este es el método que se llama a las notas después de enviar los paquetes UDP. Este es el método delegado de la clase GCDAsyncUdpSocket que he usado en mi proyecto para enviar y recibir los paquetes 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)]; } }

Una vez que pueda recibir la respuesta, podré enviar los siguientes comandos AT para configurar el Puente.

Gracias. Cualquier ayuda será apreciada.


Aquí están los pasos de solución de problemas que te recomiendo que uses:

1- Supongo que está utilizando ARC así que asegúrese de que su variable udpSocket tenga una referencia sólida en toda la comunicación asíncrona. Si se está liberando, entonces eso podría explicar la ausencia de una devolución de llamada.

2- Asegúrate de que la comunicación realmente esté sucediendo de la manera que piensas. Utilice un software como Wireshark para capturar los paquetes que se intercambian en la red. Esto debería permitirle confirmar que sus paquetes se envían al llamar a sendData: y también le permitirá confirmar si recibe o no una respuesta.

3- Asegúrese de que está utilizando el GCDAsyncUdpSocket correctamente. Teniendo en cuenta que desea transmitir un mensaje, no debería llamar a bindToPort:error: en su método setupSocket . En su lugar, debería estar llamando a enableBroadcast:error: Teniendo en cuenta que también desea recibir paquetes después de la transmisión, debe usar el connectToHost:onPort:error: para cambiar el estado del socket para permitir la comunicación bidireccional. Una vez hecho esto, puede reemplazar el uso de sendData:toHost:port:withTimeout:tag: by sendData:withTimeout:tag: Finalmente, puede llamar a beginReceiving: para que se llame al delegado para cualquier paquete entrante.

4- Si esto todavía no lo logra, le recomiendo que lea detenidamente la documentación del GCDAsyncUdpSocket que está muy bien documentado.


Puede solucionar el problema utilizando Wireshark o cualquier herramienta de captura de red. Solíamos trabajar en un tipo similar de proyecto en el que usamos Wireshark ampliamente. Si el paquete ha llegado al dispositivo (Z-Wave), enviará algún tipo de Ack. Esto ayudará a asegurar que los paquetes salgan.