Pregunta

Tengo que ser capaz de enviar un mensaje UDP y también recibir una con el fin de descubrir los dispositivos de SSDP en la red desde el iPhone.

Sé que tengo que enviar el paquete a la dirección de multidifusión y mis necesidades de solicitud HTTP a ser algo como esto:

M-SEARCH * HTTP/1.1
Host: 239.255.255.250:1900
Man: ssdp:discover
Mx: 3
ST: "urn:schemas-upnp-org:device:InternetGatewayDevice:1"

A partir de la lectura de los documentos parece que puedo hacer todo esto con CFNetwork ya pesar de la lectura (y re-lectura de la documentación) Estoy luchando para empezar. ¿Alguien puede recomendar y tutoriales o fragmentos de código para conseguirme más de la joroba inicial de aprendizaje?

Tengo la guía de programación CFNetwork:

http://developer.apple.com/ mac / biblioteca / documentación / red / conceptual / CFNetwork / CFNetwork.pdf

y la Guía del Beej Red de programación utilizando sockets de Internet:

http://beej.us/guide/bgnet/

Gracias

David

P.S.

Soy incapaz de utilizar cualquiera de las bibliotecas 3 ª parte y marcos en este caso.

¿Fue útil?

Solución 3

OK, finalmente lo ha hecho. Se han encontrado una clase de dominio público (gracias Chris) AsyncUdpSocket llamada que le permite crear un socket UDP que luego se puede activar la difusión y se une a la dirección de multidifusión.

Hay un buen método sendData, con la adición de un bucle de ejecución para evitar el bloqueo.

Espero que ayude.

David

Otros consejos

he utilizado con éxito para ejecutar AsyncUdpSocket descubrimientos SSDP y encontrar los controladores. Aquí están mis fragmentos de código:

inicializar y configurar el socket:

//  AsyncUdpSocket *ssdpSock = [[AsyncUdpSocket alloc] initWithDelegate:self];
    AsyncUdpSocket *ssdpSock = [[AsyncUdpSocket alloc] initIPv4];
    [ssdpSock setDelegate:self];

Tenga en cuenta la primera línea comentada. He encontrado en los foros AsyncUdpSocket algunos problemas con los duplicados. No creo que yo los estaba enfrentando pero lo hice de todos modos.

He añadido la comprobación de errores, y era útil porque durante mis tomas de depuración que no estaba cerrando y empecé a recibir errores de instalación del zócalo:

NSError *socketError = nil;

    if (![ssdpSock bindToPort:1900 error:&socketError]) {
        NSLog(@"Failed binding socket: %@", [socketError localizedDescription]);
        return statusController;
    }

    if(![ssdpSock joinMulticastGroup:@"239.255.255.250" error:&socketError]){
        NSLog(@"Failed joining multicast group: %@", [socketError localizedDescription]);
        return statusController;
    }

    if (![ssdpSock enableBroadcast:TRUE error:&socketError]){
        NSLog(@"Failed enabling broadcast: %@", [socketError localizedDescription]);
        return statusController;
    }

    [ssdpSock sendData:[self.discoverControllerString dataUsingEncoding:NSUTF8StringEncoding]
                toHost:@"239.255.255.250"
                  port:1900
           withTimeout:2
                   tag:1];

Aviso de los cambios que he hecho en el tiempo de espera. Y, finalmente, hizo el Configuración de la recepción, y se cierra el socket. Tenga en cuenta la toma de cerca. Desde que estoy en mi propia clase cuando estoy corriendo este -. El código anterior no funcionó para mí

[ssdpSock receiveWithTimeout: 2 tag:1];
    [NSTimer scheduledTimerWithTimeInterval: 5 target: self 
                                   selector:@selector(completeSearch:) userInfo: self repeats: NO]; 





    [ssdpSock closeAfterSendingAndReceiving];

El cambio más importante fue probablemente volviendo "NO" si no he encontrado mi controlador. La primera tuvo lugar la recepción por cierto el mensaje de descubrimiento de sí mismo volviendo. Y cuando leí a través del archivo AsyncUdpSocket.h cuidadosamente - volviendo "NO" cuando no es un paquete que busca ayudado

.

También tenga en cuenta que estoy usando ARC en mi código, pero he recopilado la AsyncUdpSocket sin el apoyo de ARC.

-(void) completeSearch: (NSTimer *)t 
{

    NSLog(@"%s",__FUNCTION__);

    //[ssdpSock close];
    //ssdpSock = nil;

}


- (BOOL)onUdpSocket:(AsyncUdpSocket *)sock 
     didReceiveData:(NSData *)data 
            withTag:(long)tag 
           fromHost:(NSString *)host 
               port:(UInt16)port
{
    NSLog(@"%s %ld %@ %d",__FUNCTION__,tag,host,port);
    NSString *aStr = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];

    NSLog(@"%@",aStr);



    NSString *compareString = [aStr stringByPaddingToLength:[self.responseString length] withString:@"." startingAtIndex:0];
    //NSLog(@"%@", compareString);
    //NSLog(@"%@", self.responseString);

    if ([compareString isEqualToString:self.responseString])
    {
        NSLog(@"String Compare, Controller Found!");
        [self.controllerList addObject:aStr];
        //NSData *controllerIP = [aStr dataUsingEncoding:NSUTF8StringEncoding];
        [[NSNotificationCenter defaultCenter] postNotificationName:@"DiscoveredController" object:nil];


        return YES;
    }

    return NO;

}

Tengo el siguiente código para la búsqueda SSDP en mi aplicación:

-(void)discoverDevices {
ssdpSock = [[AsyncUdpSocket alloc] initWithDelegate:self];
[ssdpSock enableBroadcast:TRUE error:nil];
NSString *str = @"M-SEARCH * HTTP/1.1\r\nHOST: 239.255.255.250:1900\r\nMan: \"ssdp:discover\"\r\nST: mydev\r\n\r\n";    
[ssdpSock bindToPort:0 error:nil];
[ssdpSock joinMulticastGroup:@"239.255.255.250" error:nil];
[ssdpSock sendData:[str dataUsingEncoding:NSUTF8StringEncoding] 
         toHost: @"239.255.255.250" port: 1900 withTimeout:-1 tag:1];
[ssdpSock receiveWithTimeout: -1 tag:1];
[NSTimer scheduledTimerWithTimeInterval: 5 target: self 
           selector:@selector(completeSearch:) userInfo: self repeats: NO]; }


-(void) completeSearch: (NSTimer *)t {
NSLog(@"%s",__FUNCTION__);
[ssdpSock close];
ssdpSock = nil;}

- (BOOL)onUdpSocket:(AsyncUdpSocket *)sock didReceiveData:(NSData *)data withTag:(long)tag fromHost:(NSString *)host port:(UInt16)port{
NSLog(@"%s %d %@ %d",__FUNCTION__,tag,host,port);
NSString *aStr = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
NSLog(@"%@",aStr);}

Se utiliza el AsyncUdpSocket de CocoaAsyncSocket .

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top