總體而言,SSDP協定規定了兩種發現裝置的途徑:
第一種途徑,控制端發送搜尋裝置消息,并監聽響應消息;
第二種途徑,控制端監聽裝置的宣告消息。
這兩種隻要有一種途徑成功,就實作了裝置發現。
抓包分析
以騰訊App發現XXX為例分析,假設兩台裝置加入區域網路絡後,手機擷取了IP位址192.168.1.102,而XXX擷取了IP位址192.168.1.112。
手機發送搜尋裝置消息,并監聽響應消息
圖1的tcpdump請求過程是192.168.1.102發現192.168.1.112,即手機發現XXX的過程.
首先192.168.1.102發了一個多點傳播消息,消息位址是239.255.255.250:1900,基于HTTP/1.1協定;192.168.1.112收到了多點傳播消息;并給192.168.1.102發了一條響應消息;攜帶了192.168.1.112的一些資訊;如裝置名稱,裝置描述檔案位置,裝置辨別等。
192.168.1.102收到響應就會獲得關于192.168.1.112的資訊,這就實作了192.168.1.102對192.168.1.112的發現,即手機發現了XXX裝置。
66和67兩條消息是ARP消息,位址解析協定,根據位址192.168.1.102解析其MAC位址,用于網絡層傳輸。
下面分析兩條消息的封包結構。
手機發的搜尋消息.
圖2的tcpdump資料是192.168.1.02搜尋消息的封包。
192.168.1.102每隔1s時間發一條SSDP消息到239.255.255.250:1900,請求行M-SEARCH * HTTP/1.1,有header,無body。
header攜帶了一些字段,解讀如下:
ST(Search Target),搜尋的目标是upnp:rootdevice;
MX等待響應的延時時間;
MAN消息的類型 "ssdp:discover"是搜尋消息的必要值;
HOST多點傳播位址和端口, 239.255.255.250:1900是必要值。
這條消息實作了搜尋upnp:rootdevice裝置。
手機收的響應消息。
圖3的tcpdump是192.168.1.112收到這條M-SEARCH消息後響應的tcpdump抓包資料。
響應消息是一個UDP消息,有header,無body。由于SSDP消息使用的是HTTP/1.1,是以響應行時HTTP/1.1 200 OK。
header攜帶的消息解讀如下:
Content-Type 内容類型;
Server 伺服器名字;
Content-Length 位元組機關的消息長度;
Cache-Control 告知用戶端這條消息的緩存時長,以秒為機關;
EXT;
Date 伺服器産生并發送該封包的日期和時間;
ST 搜尋目标;
USN Unique Service Name 唯一服務名稱;
Location 資源位置;
…
後面的字段是廠商自己定義的字段,是以廠商可根據需求擴充header字段。
程式設計實踐
手機端程序需要:
新起一個線程管理SSDP消息的發送,稱為搜尋線程
新起一個線程監聽響應,稱為搜尋響應監聽線程
電視果程序需要:
新起一個線程監聽搜尋消息,稱為搜尋監聽線程
收到搜尋消息後新起一個線程發送響應消息,稱為搜尋響應線程
控制端監聽裝置的宣告消息
SSDP協定還規定了目标裝置需要發送通知消息宣告線上, 如圖4所示
192.168.1.112不定時發送多點傳播消息,宣告裝置線上,消息基于HTTP/1.1,攜帶了裝置的一些資訊,如裝置名稱,裝置描述檔案位置,裝置辨別等。192.168.1.102收到這個NOTIFY消息時,會獲得192.168.1.112的資訊,進而完成了裝置發現過程。下面分析NOTIFY消息的封包格式。
線上消息
NOTIFY消息有header,無body。與M-SEARCH消息的響應消息相似。在Header裡定義了裝置相關的字段和值。
程式設計實踐
手機端上:
新起一個線程監聽線上消息,稱為線上監聽線程.
電視果上:
新起一個線程管理線上消息的發送,稱為線上消息線程.
Bonjour協定
圖1的tcpdump發現過程是192.168.1.100發現192.168.1.112的過程,即手機發現XXX的過程.
mDNS使用5353端口,mDNS協定定義了協定消息的基本格式和順序:
224.0.0.251/5353是mDNS使用的多點傳播消息位址;
xx:xx:xx:255/5353(如192.168.1.255:5353)是mDNS使用的廣播消息位址。
為搜所裝置,手機将query消息發到多點傳播位址。而電視果将response消息同時發多點傳播位址和廣播位址。
為及時發現裝置,XXX會每10s就發一次response消息,稱為不請自來的消息,雖然并沒有收到query消息也會發response消息。
在圖1的發現過程看到192.168.1.102每次發6條消息,3條多點傳播消息,3條廣播消息。
手機上發的消息
圖2的tcpdump手機上發的query消息.
這個query消息的Queries有3條記錄:
_airplay._tcp.local
_raop._tcp.local
_airplay._tcp.local
消息從192.168.1.100:5353(手機上)發送到了224…0.0251:5353,該消息是一個多點傳播消息。
1和3是一樣的,是以這個query消息手機搜尋支援_airplay._tcp和_raop._tcp的裝置。
XXX上發的Query Response消息:
XXX上每一次發送的消息都包含6條沒,3條廣播到192.168.1.255:5353,另3條多點傳播到224.0.0.251:5353,多點傳播和廣播的消息内容重複的,是以電視果總共發了3中query response消息,每一種消息包含一種服務記錄:
wlan0.local: type A, class IN, cache flush, addr 192.168.1.112
_raop._tcp.local: type PTR, class IN, CCB8A813D00E@\347\224\265\350\247\206\346\236\234(103)._raop._tcp.local
_airplay._tcp.local: type PTR, class IN, \347\224\265\350\247\206\346\236\234(103)._airplay._tcp.local
這6條消息都是"不請自來"的消息,因為沒有收到query消息而發的query response消息。
開源庫JmDNS.
XXX上裝置發現的過程:
首先probing消息連續發3次,間隔250ms;
然後announcing消息連續發2次,間隔1分鐘;
在announced狀态之後,Renewer每隔10s鐘發送一次消息,每次都是6條,3條多點傳播3條廣播,類似DLNA的線上消息;
announced狀态之後的消息在在圖1發現過程中可以看到,但是probing和announcing的過程還沒有找到tcpdump分析的方法。