【问题标题】:Best way to parse SSDP Discovery in Objective C在 Objective C 中解析 SSDP 发现的最佳方法
【发布时间】:2012-11-20 15:56:56
【问题描述】:

我正在开发一个非常简单的应用程序来发现使用 SSDP 的设备,并且我正在尝试找到解析此命令响应的最简单方法。我试图避免做一堆 NSString 或正则表达式操作。

我尝试了以下两种方法:

方法一: 使用 GCDAsyncUdpSocket,我能够成功发送发现命令并获得以下响应:


HTTP/1.1 200 正常
缓存控制:max-age=300
ST: roku:ecp
USN: uuid:roku:ecp:1234567890
分机:
服务器:Roku UPnP/1.0 MiniUPnPd/1.4
地点:http://192.168.XX.XX:8060/


这看起来像一个常规的 HTTP 响应,但是使用 GCDAsyncUdpSocket,我得到了一个 NSData 对象的响应,我可以轻松地将它转换为一个 NSString。但是,理想的方法是以某种方式将其转换为 NSHTTPURLResponse,然后使用其方法获取字段值。知道这是否可以做到吗?

方法二: 我尝试使用常规 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!");   
    }

当我这样做时,连接成功,但我在 NSURLConnection 的 didFailWithError 委托中收到以下错误:

失败的错误域=NSPOSIXErrorDomain Code=47“操作无法完成。协议族不支持地址族” UserInfo=0x8875940 {NSErrorFailingURLKey=http://239.255.255.250:1900/, NSErrorFailingURLStringKey=http:// /239.255.255.250:1900/}

此错误仅在我使用端口 1900 时发生,如果我忽略此端口或使用另一个对 HTTP 更友好的端口(例如 8080),则此方法有效,但显然我尝试发现的设备无法正确响应,除非它获得在 1900 端口请求。

感谢您提供的任何帮助。

【问题讨论】:

    标签: objective-c ios http nsurlrequest ssdp


    【解决方案1】:

    端口 1900 已针对 SSDP 固定。所有 UPnP 设备都固定在此端口上侦听,并且连接节点期望这样做。你不能改变它。 “开箱即用”是 UPnP 设计目标的一部分。此外,我的 Cocoa 专业知识非常有限,但我认为 NSHTTPURLResponse 不会让您的事情变得更简单。 [NSHTTPURLResponse allHeaderFields] 返回NSDictionary,这意味着您不再知道标头字段的原始顺序是什么。您需要知道Ext: 之后发生了什么,这是一个元标题。

    我建议要么自己解析响应,这不应该比一个循环复杂得多,按行分隔响应,然后按: 拆分。或者,不要尝试使用自己的 SSDP 握手,而是使用现成的 Cocoish 库,例如 Upnpx、Cyber​​link 或 Platinum。对于发现阶段来说,这可能感觉像是不恰当的重型火炮,但我想知道在那之后你会对设备做什么,而不是实际尝试在设备上调用一些操作。

    【讨论】:

    • 感谢 Pavel,我最终使用了 GCDAsyncUdpSocket 并手动解析了响应。结果并没有我最初想的那么复杂。
    猜你喜欢
    • 2011-04-29
    • 1970-01-01
    • 1970-01-01
    • 2010-09-22
    • 1970-01-01
    • 1970-01-01
    • 2010-09-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多