Getting SSDP Response Using CocoaAsyncSocket in Swift

I am trying to get SSDP response using swift with CocoaAsyncSocket library ( https://github.com/robbiehanson/CocoaAsyncSocket )

I can successfully send the M-Search command to the multicast group and get a response, I looked at wirehark ( http://i.imgur.com/pn6LB7R.png ): I see that the M-Search packets are coming out and the answers are coming back, but I never get NSData in my application. (By the way, I'm only looking for Roku at the moment)

I implemented the GCDAsyncUdpSocketDelegate delegate and added fun.itReceiveData, but I never receive data.

I suspect something is wrong in this section:

ssdpSocket = GCDAsyncUdpSocket(delegate: self, delegateQueue: dispatch_get_main_queue()) ssdpSocket.bindToPort(ssdpPort, error: &error) ssdpSocket.beginReceiving(&error) ssdpSocket.enableBroadcast(true, error: &error) ssdpSocket.connectToHost(ssdpAddres, onPort: ssdpPort, error: &error) ssdpSocket.joinMulticastGroup(ssdpAddres, error: &error) 

See the sample code below:

 import UIKit class ViewController: UIViewController, GCDAsyncUdpSocketDelegate { //ssdp stuff var ssdpAddres = "239.255.255.250" var ssdpPort:UInt16 = 1900 var ssdpSocket:GCDAsyncUdpSocket! var ssdpSocketRec:GCDAsyncUdpSocket! var error : NSError? override func viewDidLoad() { super.viewDidLoad() ssdpSocket = GCDAsyncUdpSocket(delegate: self, delegateQueue: dispatch_get_main_queue()) ssdpSocket.bindToPort(ssdpPort, error: &error) ssdpSocket.beginReceiving(&error) ssdpSocket.enableBroadcast(true, error: &error) ssdpSocket.connectToHost(ssdpAddres, onPort: ssdpPort, error: &error) ssdpSocket.joinMulticastGroup(ssdpAddres, error: &error) //replace ST:roku:ecp with ST:ssdp:all to view all devices let data = "M-SEARCH * HTTP/1.1\r\nHOST: 239.255.255.250:1900\r\nMAN: \"ssdp:discover\"\r\nMX: 3\r\nST: roku:ecp\r\nUSER-AGENT: iOS UPnP/1.1 TestApp/1.0\r\n\r\n".dataUsingEncoding(NSUTF8StringEncoding) ssdpSocket.sendData(data, withTimeout: 1, tag: 0) } func udpSocket(sock:GCDAsyncUdpSocket!,didConnectToAddress data : NSData!){ println("didConnectToAddress") println(data) } func udpSocket(sock: GCDAsyncUdpSocket!, didReceiveData data: NSData!, fromAddress address: NSData!, withFilterContext filterContext: AnyObject!) { println("didReceiveData") println(data) } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } } 
+5
source share
1 answer

After long games with the code, I got it to work, I post the code here to help anyone else with this problem.

when i deleted:

 ssdpSocket.connectToHost(ssdpAddres, onPort: ssdpPort, error: &error) 

I was able to get the data, I suspect that somehow blocked it. I don’t know how and why, I assume that I do not need to connect to the host as its multicast

Now it works using the following code:

 let mSearchData = "M-SEARCH * HTTP/1.1\r\nHOST: 239.255.255.250:1900\r\nMAN: \"ssdp:discover\"\r\nMX: 3\r\nST: ssdp:all\r\nUSER-AGENT: iOS UPnP/1.1 TestApp/1.0\r\n\r\n".dataUsingEncoding(NSUTF8StringEncoding) //all devices override func viewDidLoad() { super.viewDidLoad() //send M-Search ssdpSocket = GCDAsyncUdpSocket(delegate: self, delegateQueue: dispatch_get_main_queue()) ssdpSocket.sendData(mSearchData, toHost: ssdpAddres, port: ssdpPort, withTimeout: 1, tag: 0) //bind for responses ssdpSocket.bindToPort(ssdpPort, error: &error) ssdpSocket.joinMulticastGroup(ssdpAddres, error: &error) ssdpSocket.beginReceiving(&error) } 

The didReceiveData function is now called, and I can print the answer:

  func udpSocket(sock: GCDAsyncUdpSocket!, didReceiveData data: NSData!, fromAddress address: NSData!, withFilterContext filterContext: AnyObject!) { var host: NSString? var port1: UInt16 = 0 GCDAsyncUdpSocket.getHost(&host, port: &port1, fromAddress: address) println("From \(host!)") let gotdata: NSString = NSString(data: data!, encoding: NSUTF8StringEncoding)! println(gotdata) } 
+8
source

Source: https://habr.com/ru/post/1209890/


All Articles