Domanda

Ho bisogno di essere in grado di inviare un messaggio UDP e anche ricevere uno al fine di rilevare i dispositivi SSDP sulla rete da iPhone.

Lo so che ho bisogno di inviare il pacchetto all'indirizzo multicast e le mie HTTP richiesta deve essere simile a questa:

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

Dalla lettura dei documenti sembra che io possa fare tutto questo con CFNetwork e nonostante la lettura (e ri-leggere la documentazione) Ho difficoltà a iniziare. Qualcuno può consigliare e tutorial o frammenti di codice per farmi superare la gobba di apprendimento iniziale?

Ho la guida di programmazione CFNetwork:

http://developer.apple.com/ mac / library / Documentation / networking / concettuale / CFNetwork / CFNetwork.pdf

e di Beej Guida alla rete di programmazione utilizzando Internet Sockets:

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

Grazie

Dave

P.S.

Sono in grado di utilizzare una qualsiasi delle biblioteche 3rd party e framework in questo caso.

È stato utile?

Soluzione 3

OK, finalmente fatto. Trovato una classe di dominio pubblico (grazie Chris) chiamato AsyncUdpSocket che consente di creare un socket UDP che è quindi possibile attivare la trasmissione e unirsi l'indirizzo multicast.

C'è un bel metodo di sendData, con l'aggiunta di un ciclo corsa per evitare il blocco.

La speranza che aiuta.

Dave

Altri suggerimenti

ho usato con successo per eseguire AsyncUdpSocket SSDP Discovery e trovare i controllori. Qui sono i miei frammenti di codice:

inizializzazione e la configurazione della presa:

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

Si noti la prima linea commentata. Ho trovato sul forum AsyncUdpSocket alcuni problemi con i duplicati. Non credo che io li stavo affrontando ma l'ho fatto comunque.

Ho aggiunto il controllo degli errori, ed è stato utile, perché durante i miei prese il debug non stava chiudendo e ho cominciato a ricevere gli errori di impostazione presa:

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

notare i cambiamenti che ho fatto per il time out. E poi finalmente ha fatto la messa a punto di ricezione, e chiuso il socket. Si noti la presa stretta. Dato che io sono nella mia classe quando sto facendo funzionare questo -. Il codice di cui sopra non ha funzionato per me

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





    [ssdpSock closeAfterSendingAndReceiving];

Il cambiamento più importante probabilmente stava tornando "NO" se non ho trovato il mio controller. La prima ricezione è inciso il messaggio scoperta stessa a tornare. E quando ho letto attraverso il file AsyncUdpSocket.h con attenzione - il ritorno "NO" quando non è un pacchetto che si sta cercando aiutato

.

Si noti inoltre che sto usando ARC nel mio codice, ma ho compilato l'AsyncUdpSocket senza il supporto 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;

}

Ho il seguente codice per SSDP ricerca nella mia app:

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

Si utilizza la AsyncUdpSocket da CocoaAsyncSocket .

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top