2010-07-07 36 views
7

IPhone'dan ağ üzerindeki SSDP cihazlarını keşfetmek için bir UDP mesajı gönderebilmem ve bir tane de almam gerekiyor.SSDP'de iPhone

ben noktaya yayın adresine paket göndermek gerektiğini biliyoruz ve benim HTTP isteği şuna benzer gerekir: ben CFNetwork ve tüm yapabilirsiniz görünür docs okuyunca

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

okumaya rağmen (ve belgeleri yeniden okurken) başlamak için mücadele ediyorum. İlk öğrenim kümesinin üzerinden beni kimseye tavsiye edebilecek öğreticiler veya kod parçacıkları önerebilir mi?

Ben CFNetwork programlama rehberi var:

Dave

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

Teşekkür

:

http://developer.apple.com/mac/library/documentation/Networking/Conceptual/CFNetwork/CFNetwork.pdf

ve Ağ programlama kullanarak internet Soketlere Beej Kılavuzu

P.S.

Bu örnekte üçüncü taraf kitaplıklarını ve çerçevelerini kullanamıyorum.

cevap

2

Tamam, sonunda yapıldı. AsyncUdpSocket olarak adlandırılan ve daha sonra yayın yapmayı ve çok noktaya yayın adresine katılabilen bir UDP soketi oluşturmanızı sağlayan genel alanda (teşekkürler Chris) bir sınıf buldum.

Engellemeyi önlemek için bir çalışma döngüsüne eklenerek tamamlanmış güzel bir SendData yöntemi vardır.

Bu yardımcı olur umarım.

Dave

4

benim app SSDP arama için aşağıdaki kod var:

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

O CocoaAsyncSocket den AsyncUdpSocket kullanır.

+4

Merhaba Savvybud, iyi görünüyor, ama başımın tepesinden (bir süre önce bunu yaptım) bindToPort ile sorununuzun olduğunu düşünüyorum. Eminim ki bu mesajlar gönderilecek ve 1900 olmamaları gereken bağlantı noktasıdır. Bunu sıfır olarak ayarlarsanız, sistem bir tane ayırır ve çalışması gerekir. SendData iyi görünüyor. –

+0

Sihirli Kurşun Dave, sen adamsın! – savvybud

4

SSDP Discovery'yi çalıştırmak ve denetleyicileri bulmak için AsyncUdpSocket'ı başarıyla kullandım.

başlat ve kurulum soket: İlk satır dışarı yorumladı

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

Not İşte benim kod snippet'leridir. AsyncUdpSocket forums'da yinelenen bazı sorunlar buldum. Onlarla yüzleştiğimi sanmıyorum ama yine de yaptım. Ben yuvalarını kapatılıyor değildi ve ben alıyorum soket kurulum hataları başladı çünkü benim ayıklama sırasında

hata denetimi eklendi ve yararlı oldu:

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

Bildirim ben zaman aşımına yapmış olduğunuz değişiklikleri. Ve sonra nihayet kurulumunu yaptı ve soketi kapattı. Soketi kapatın. Bunu yaparken kendi sınıfımda olduğum için - yukarıdaki kod benim için çalışmadı.

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





    [ssdpSock closeAfterSendingAndReceiving]; 

En önemli değişiklik, denetleyicimi bulamadığı takdirde "NO" döndürüyordu. İlk alma tesadüfen keşif mesajının kendisi geri geldi. Ve AsyncUdpSocket.h dosyasını dikkatli bir şekilde okurken, bir paket olmadığında "HAYIR" ifadesini döndürdüğünüzde, yardım ettiniz.

Ayrıca, kodumda ARC kullanıyorum ama ARC desteği olmadan AsyncUdpSocket'i derledim.

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

} 
+0

Bir sony eylem kamını bulmak için yukarıda açıklanan yaklaşımı kullanıyorum. CFSocketSetAddress dinleme hatası hata ayıklayıcısında [ssdpSock bindToPort: 1900 hatası: & socketError] satırında görünür: 102, ancak her şey yolunda, keşif başarıyla gerçekleşir. Bu başarısızlık şu anlama geliyor: 102 Bilmiyorum. Herhangi bir fikri olan var mı? PS: Biraz daha derine inerim, bunun olduğu satır CFSocketError error = CFSocketSetAddress (TheSocket4, (__bridge CFDataRef) address4); hata değeri kCFSocketSuccess şeklindedir. –