我正在开发一个非常简单的应用程序来发现一个使用SSDP的设备,并且我正在试图找到从这个命令解析响应的最简单的方法。我试图避免做一堆NSString或正则表达式操作。
我尝试了以下两种方法:
方法1:使用GCDAsyncUdpSocket,我能够成功地发送发现命令并获得以下响应:
HTTP/1.1 200正常
缓存-控制:最大年龄=300
ST: roku:ecp
USN: uuid:roku:ecp:1234567890
电话分机:
服务器: Roku UPnP/1.0 MiniUPnPd/1.4
这看起来像是一个常规的HTTP响应,但是使用GCDAsyncUdpSocket,我将响应作为一个NSData对象获得,我可以很容易地将其转换为NSString。但是,理想的方法是将其转换为NSHTTPURLResponse,然后使用其方法获取字段值。知道能不能做到这一点吗?
方法2:我尝试使用普通的NSURLRequest来尝试发送这个命令,然后我就可以得到一个NSHTTPURLResponse了。但是,由于SSDP发现命令要求我将此请求发送到端口1900,所以我继续收到一个错误。我使用下面的代码发送" HTTP“请求,我知道它不是严格的HTTP,但我认为发送这个UDP命令可能更容易,因为需求看起来非常类似于HTTP。
NSURL *url = [NSURL URLWithString:@"http://239.255.255.250:1900"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url
cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0];
[request setHTTPMethod:@"M-SEARCH *"];
[request setValue:@"239.255.255.250:1900" forHTTPHeaderField:@"Host"];
[request setValue:@"\"ssdp:discover\"" forHTTPHeaderField:@"Man"];
[request setValue:@"roku:ecp" forHTTPHeaderField:@"ST"];
NSURLConnection *connection = [[NSURLConnection alloc]initWithRequest:request delegate:self startImmediately:YES];
if (connection)
{
NSLog(@"Connection success!");
}
else
{
NSLog(@"Connection failed!");
}
当我这样做时,连接是成功的,但是我在didFailWithError委托NSURLConnection中得到了以下错误:
“无法完成操作。协议族不支持的地址族”UserInfo=0x8875940 {NSErrorFailingURLKey=http://239.255.255.250:1900/,NSErrorFailingURLStringKey=http://239.255.255.250:1900/}
只有当我使用端口1900时才会发生此错误,如果我省略了这个错误,或者使用了另一个更友好的HTTP端口(如8080 ),则此错误才会发生,但显然,除非在端口1900中获得请求,否则我试图发现的设备不会正确响应。
谢谢你能提供的任何帮助。
发布于 2012-11-21 09:33:43
端口1900是为SSDP固定的。所有的UPnP设备都被固定在这个端口上侦听,连接节点期望这样做。你不能改变它。“开箱即用”是UPnP设计目标的一部分。此外,我的可可专业知识非常有限,但我认为NSHTTPURLResponse
不会使事情变得更简单。[NSHTTPURLResponse allHeaderFields]
返回NSDictionary
,这意味着您不再知道头字段的原始顺序是什么。你需要知道在Ext:
之后的是什么,它是一个元头。
我建议您自己解析响应,这不应该比一个周期复杂得多,将响应按行分隔,然后按:
拆分。或者使用现成的Cocoish库,比如Upnpx、数链链接或白金,而不是尝试自己的SSDP握手。仅仅在发现阶段,它可能感觉就像不恰当的重炮,但我想知道在那之后你还会对这个设备做些什么,除了实际尝试在这个设备上调用一些动作之外。
https://stackoverflow.com/questions/13477025
复制相似问题