2010-07-07 24 views
7

पर एसएसडीपी मुझे आईडीपी संदेश भेजने और आईफोन से नेटवर्क पर एसएसडीपी उपकरणों को खोजने के लिए एक प्राप्त करने की आवश्यकता है।आईफोन

मुझे पता है कि मैं बहुस्त्र्पीय पते पर पैकेट भेजने की जरूरत है और मेरे HTTP अनुरोध कुछ इस तरह ही नज़र आना चाहिए:

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

डॉक्स ऐसा लगता है कि मैं CFNetwork और साथ यह सब कर सकते हैं पढ़ने से पढ़ने के बावजूद (और दस्तावेज़ों को फिर से पढ़ना) मैं शुरू करने के लिए संघर्ष कर रहा हूं। प्रारंभिक लर्निंग कूबड़ पर मुझे प्राप्त करने के लिए कोई भी सिफारिश कर सकता है और ट्यूटोरियल या कोड स्निपेट कर सकता है?

मैं CFNetwork प्रोग्रामिंग गाइड मिल गया है:

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

और नेटवर्क प्रोग्रामिंग का उपयोग करते हुए इंटरनेट सॉकेट करने के लिए बीज की मार्गदर्शिका:

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

धन्यवाद

डेव

पीएस

मैं इस उदाहरण में किसी भी तृतीय पक्ष पुस्तकालयों और ढांचे का उपयोग करने में असमर्थ हूं।

उत्तर

2

ठीक है, आखिरकार इसे किया। सार्वजनिक डोमेन (धन्यवाद क्रिस) में एक वर्ग मिला जिसे AsyncUdpSocket कहा जाता है जो आपको एक यूडीपी सॉकेट बनाने देता है जिसे आप प्रसारण चालू कर सकते हैं और मल्टीकास्ट पते में शामिल हो सकते हैं।

अवरोध रोकने से रोकने के लिए एक रन लूप में जोड़ने के साथ एक अच्छी sendData विधि है।

उम्मीद है कि मदद करता है।

डेव

4

मैं अपने अनुप्रयोग में SSDP खोज के लिए निम्न कोड है:

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

यह CocoaAsyncSocket से AsyncUdpSocket उपयोग करता है।

+4

हाय Savvybud, ठीक दिखता है, लेकिन मेरे सिर के शीर्ष से (यह कुछ समय पहले मैंने ऐसा किया था) मुझे लगता है कि आपकी समस्या bindToPort के साथ है। मुझे पूरा यकीन है कि यह बंदरगाह है कि संदेश वापस भेज दिए जाएंगे और 1 9 00 नहीं होने चाहिए क्योंकि यह मल्टीकास्ट के लिए आरक्षित है। यदि आप इसे शून्य पर सेट करते हैं तो सिस्टम एक आवंटित करेगा और इसे काम करना चाहिए। sendData ठीक दिखता है। –

+0

जादू बुलेट डेव, आप आदमी हैं! – savvybud

4

मैंने एसएसडीपी डिस्कवरी चलाने और नियंत्रकों को खोजने के लिए सफलतापूर्वक AsyncUdpSocket का उपयोग किया है।

प्रारंभ और सेटअप सॉकेट:

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

नोट पहली पंक्ति पर टिप्पणी की यहाँ मेरी कोड के टुकड़े कर रहे हैं। मुझे AsyncUdpSocket forums पर डुप्लीकेट के साथ कुछ समस्याएं मिलीं। मुझे नहीं लगता कि मैं उनका सामना कर रहा था लेकिन मैंने इसे किसी भी तरह से किया।

मैं त्रुटि जाँच जोड़ा, और यह उपयोगी था क्योंकि मेरे डीबगिंग के दौरान मैं सॉकेट बंद करने नहीं गया था और मैं हो रही सॉकेट सेटअप विफलताओं शुरू कर दिया:

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

सूचना परिवर्तन मैं समय के लिए बाहर करने के लिए बना दिया है। और फिर अंततः सेटअप प्राप्त किया, और सॉकेट बंद कर दिया। सॉकेट बंद करें नोट करें। चूंकि मैं अपनी कक्षा में हूं जब मैं इसे चला रहा हूं - उपरोक्त कोड मेरे लिए काम नहीं करता है।

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





    [ssdpSock closeAfterSendingAndReceiving]; 

सबसे महत्वपूर्ण परिवर्तन शायद "नहीं" लौटा रहा था अगर मुझे मेरा नियंत्रक नहीं मिला। पहली बार आकस्मिक रूप से खोज संदेश स्वयं वापस आ रहा था। और जब मैं AsyncUdpSocket.h फ़ाइल को ध्यान से पढ़ता हूं - "नहीं" लौटाता है जब यह एक पैकेट नहीं है जिसे आप मदद की तलाश में हैं।

यह भी ध्यान दें कि मैं अपने कोड में एआरसी का उपयोग कर रहा हूं लेकिन मैंने एआरसी समर्थन के बिना AsyncUdpSocket संकलित किया।

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

मैं एक सोनी एक्शन कैम खोजने के लिए उपर्युक्त वर्णित दृष्टिकोण का उपयोग कर रहा हूं। लाइन पर [ssdpSock bindToPort: 1900 त्रुटि: & socketError] डीबगर पर दिखाई देता है CFSocketSetAddress सुनो विफलता: 102, हालांकि सब कुछ ठीक है, खोज सफलतापूर्वक होती है। क्या बिल्ली का मतलब यह विफलता है: 102 मुझे नहीं पता। किसी को भी कोई विचार? पीएस: यदि मैं थोड़ा गहरा खोदता हूं, तो यह लाइन जहां होती है CFSocketError त्रुटि = CFSocketSetAddress (theSocket4, (__bridge CFDataRef) पता 4); त्रुटि मान kCFSocketSuccess है –