在 Swift 中解析 UPnP 响应?
Parsing A UPnP Response In Swift?
这个问题可能不需要那么具体,但我正在做一个搜索 UPnP 设备的项目(效果很好)。
我是这样获取数据的;
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)
//print(host)
let response: NSString = NSString(data: data!, encoding: NSUTF8StringEncoding)!
print(response)
}
数据响应作为 NSString 返回,看起来像这样;
HTTP/1.1 200 OK
CACHE-CONTROL: max-age=120
DATE: Sun, 31 Jan 2016 22:47:45 GMT
ST: upnp:rootdevice
USN: uuid:f7a65ab0-f527-4b85-a8ad-68104aa2b322::upnp:rootdevice
EXT:
SERVER: Linux/BHR4 UPnP/1.1 MiniUPnPd/1.8
LOCATION: http://192.168.1.1:49420/rootDesc.xml
OPT: "http://schemas.upnp.org/upnp/1/0/"; ns=01
01-NLS: 1
BOOTID.UPNP.ORG: 1
CONFIGID.UPNP.ORG: 1337
HTTP/1.1 200 OK
Cache-Control: max-age=600
EXT:
Location: http://192.168.1.1:1901/root.xml
SECURELOCATION.UPNP.ORG: https://192.168.1.1:1902/root.xml
Server: Linux/3.4 UPnP/2.0 bhr4/1.2
ST: upnp:rootdevice
USN: uuid:9518ecfc-cf2f-57e4-bb23-5182aa6a23cd::upnp:rootdevice
DATE: Wed, 19 Jan 2000 02:39:56 GMT
BOOTID.UPNP.ORG: 1
HTTP/1.1 200 OK
Cache-Control: max-age=600
EXT:
Location: http://192.168.1.1:1901/root.xml
SECURELOCATION.UPNP.ORG: https://192.168.1.1:1902/root.xml
ST: urn:schemas-upnp-org:device:ManageableDevice:2
USN: uuid:9518acfc-cf2f-57e4-cc23-5a12aa6a23cd::urn:schemas-upnp-org:device:ManageableDevice:2
Server: Linux/3.4 UPnP/2.0 bhr4/1.2
DATE: Wed, 19 Jan 2000 02:39:56 GMT
BOOTID.UPNP.ORG: 1
我对如何解析 XML 或 JSON 响应有一些了解,但由于此响应似乎只是一个冗长的字符串,我想弄清楚如何解析将数据放入字典中,这样我就可以做一个;
for item in response {
print(item.location)
}
这不一定是UPnP特有的,而是一个整体把握的前提。
不久前我正在研究 swift UPNP 库。
这是我使用正则表达式的一种方式:
https://github.com/ambientlight/ambientUPNP/blob/master/ambientUPNP/SSDPMessage.swift
您可以用于解析 SSDP 消息,但是对于 UPNP GENA 事件,您不应该使用这种方法,因为它们是通过 TCP 进行的,因此您有一个流套接字,您应该相应地将其作为流读取。看看这里:
https://github.com/ambientlight/ambientUPNP/blob/master/ambientUPNP/components/HTTPInternals.swift
参考(从UDP套接字读取-定长):
https://github.com/ambientlight/ambientUPNP/blob/master/ambientUPNP/SSDPServer.swift
self.readMulticastSocket = try PosixInternals.initMulticastUDPSocket(SSDPDefaultPort, multicastAddress: SSDPMulticastAddress)
let readMulticastSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_READ, UInt(readMulticastSocket), 0, _readMulticastQueue)
dispatch_source_set_event_handler(readMulticastSource) {
do {
let (data, senderAddress) = try PosixInternals.recvData(self.readMulticastSocket, readSize: SSDPDefaultReadSize)
let message = try SSDPMessage.messageWithDataAndAddress(data, senderAddress: senderAddress)
//print("\(message)\n")
self._processMessage(message)
} catch {
print(error)
}
}
这个问题可能不需要那么具体,但我正在做一个搜索 UPnP 设备的项目(效果很好)。
我是这样获取数据的;
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)
//print(host)
let response: NSString = NSString(data: data!, encoding: NSUTF8StringEncoding)!
print(response)
}
数据响应作为 NSString 返回,看起来像这样;
HTTP/1.1 200 OK
CACHE-CONTROL: max-age=120
DATE: Sun, 31 Jan 2016 22:47:45 GMT
ST: upnp:rootdevice
USN: uuid:f7a65ab0-f527-4b85-a8ad-68104aa2b322::upnp:rootdevice
EXT:
SERVER: Linux/BHR4 UPnP/1.1 MiniUPnPd/1.8
LOCATION: http://192.168.1.1:49420/rootDesc.xml
OPT: "http://schemas.upnp.org/upnp/1/0/"; ns=01
01-NLS: 1
BOOTID.UPNP.ORG: 1
CONFIGID.UPNP.ORG: 1337
HTTP/1.1 200 OK
Cache-Control: max-age=600
EXT:
Location: http://192.168.1.1:1901/root.xml
SECURELOCATION.UPNP.ORG: https://192.168.1.1:1902/root.xml
Server: Linux/3.4 UPnP/2.0 bhr4/1.2
ST: upnp:rootdevice
USN: uuid:9518ecfc-cf2f-57e4-bb23-5182aa6a23cd::upnp:rootdevice
DATE: Wed, 19 Jan 2000 02:39:56 GMT
BOOTID.UPNP.ORG: 1
HTTP/1.1 200 OK
Cache-Control: max-age=600
EXT:
Location: http://192.168.1.1:1901/root.xml
SECURELOCATION.UPNP.ORG: https://192.168.1.1:1902/root.xml
ST: urn:schemas-upnp-org:device:ManageableDevice:2
USN: uuid:9518acfc-cf2f-57e4-cc23-5a12aa6a23cd::urn:schemas-upnp-org:device:ManageableDevice:2
Server: Linux/3.4 UPnP/2.0 bhr4/1.2
DATE: Wed, 19 Jan 2000 02:39:56 GMT
BOOTID.UPNP.ORG: 1
我对如何解析 XML 或 JSON 响应有一些了解,但由于此响应似乎只是一个冗长的字符串,我想弄清楚如何解析将数据放入字典中,这样我就可以做一个;
for item in response {
print(item.location)
}
这不一定是UPnP特有的,而是一个整体把握的前提。
不久前我正在研究 swift UPNP 库。 这是我使用正则表达式的一种方式: https://github.com/ambientlight/ambientUPNP/blob/master/ambientUPNP/SSDPMessage.swift
您可以用于解析 SSDP 消息,但是对于 UPNP GENA 事件,您不应该使用这种方法,因为它们是通过 TCP 进行的,因此您有一个流套接字,您应该相应地将其作为流读取。看看这里: https://github.com/ambientlight/ambientUPNP/blob/master/ambientUPNP/components/HTTPInternals.swift
参考(从UDP套接字读取-定长): https://github.com/ambientlight/ambientUPNP/blob/master/ambientUPNP/SSDPServer.swift
self.readMulticastSocket = try PosixInternals.initMulticastUDPSocket(SSDPDefaultPort, multicastAddress: SSDPMulticastAddress)
let readMulticastSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_READ, UInt(readMulticastSocket), 0, _readMulticastQueue)
dispatch_source_set_event_handler(readMulticastSource) {
do {
let (data, senderAddress) = try PosixInternals.recvData(self.readMulticastSocket, readSize: SSDPDefaultReadSize)
let message = try SSDPMessage.messageWithDataAndAddress(data, senderAddress: senderAddress)
//print("\(message)\n")
self._processMessage(message)
} catch {
print(error)
}
}