基於DLNA的UPNP協議的分析及實現
1 引言
UPnP 全名是Universal Plug and Play,主要是微軟在推行的一個標準。簡單的來說,UPnP 最大的願景就是希望任何裝置只要一接上網路,所有在網路上的裝置馬上就能知道有新裝置加入,這些裝置彼此之間能互相溝通,更能直接使用或控制它,一切都不需要設定,完全的Plug and Play。
舉個例子來說:
Mary在她的計算機中儲存了大量數碼相機拍攝的照片。當朋友Karen 來拜訪時, Mary在起居室拿起與等離子電視機配套的紅外線(IR)遙控器,從電視所顯示的列表中挑選她感興趣的照片,向Karen在電視螢幕上展示一下這些照片。這過程中就使用了UPnP協議。
2 UPnP的結構規範
2.1 UPnP的基本元件
服務、裝置和控制點是UPnP網路的基本元件。其元件圖如圖1所示:
圖1 UPnP元件圖
● 服務(Service)
在UPnP網路中,最小的控制單元就是服務。服務描述的是裝置在不同的情況下的活動和裝置的狀態。例如,時鐘服務可以表述為時間變化(狀態變化)、當前的時間(時鐘的狀態)以及設定時間和讀取時間兩個活動,通過這兩個活動.你就可以控制服務。
● 裝置(Device)
UPnP網路中定義的裝置具有很廣泛的含義,各種各樣的家電、電腦外設、智慧裝置、無線裝置、個人電腦等等都可以成為其中一員。一個UPnP裝置可以是多個服務的載體和多個子裝置的巢狀集。例如一臺印表機有提供列印這樣的服務;一臺電視有提供收訊的服務,這些都屬於裝置。
● 控制點(ControlPoint)
在UPnP網路中,控制點指的是可以發現並控制其它裝置的控制裝置。在UPnP網路中,裝置可以和控制點合併。也就是說,同一個裝置,可以同時具有裝置的功能和控制點的功能,即可以作為裝置提供服務,也可以作為控制點發現和控制其它裝置。
2.2 UPnP部分術語
● UUID
UUID含義是通用唯一識別碼(Universally Unique Identifier),其目的是讓分散式系統中的所有元素,都有唯一的辨識資訊,而不需要透過中央控制端來做辨識資訊的指定。其格式為xxxxxxxx-xxxx-xxxx-xxxxxxxxxxxxxxxx(8-4-4-16),分別為當前日期和時間,時鐘序列,全域性唯一的IEEE機器識別號,如果有網絡卡,從網絡卡mac地址獲得,沒有網絡卡以其他方式獲得。
● UDN
單一裝置名(Unique Device Name),基於UUID,表示一個裝置。在不同的時間,對於同一個裝置此值應該是唯一的。
● URI
Web上可用的每種資源 - HTML文件、影象、視訊片段、程式等 - 由一個通用資源標誌符(Universal Resource Identifier, 簡稱"URI")進行定位。 URI一般由三部分組成:訪問資源的命名機制;存放資源的主機名;資源自身的名稱,由路徑表示。考慮下面的URI,它表示了當前的HTML 4.0規範:http://www.webmonkey.com.cn/html/html40/它表示一個可通過HTTP協議訪問的資源,位於主機www.webmonkey.com.cn上,通過路徑“/html/html40”訪問。
● URL
URL是URI命名機制的一個子集,URL是Uniform Resource Location的縮寫,譯為“統一資源定位符”。通俗地說,URL是Internet上用來描述資訊資源的字串,主要用在各種www客戶程式和伺服器程式上。採用URL可以用一種統一的格式來描述各種資訊資源,包括檔案、伺服器的地址和目錄等。
● URN
URN:URL的一種更新形式,統一資源名稱(URN, Uniform Resource Name)。唯一標識一個實體的識別符號,但是不能給出實體的位置。標識永續性 Internet資源。URN可以提供一種機制,用於查詢和檢索定義特定名稱空間的架構檔案。儘管普通的URL可以提供類似的功能,但是在這方面,URN 更加強大並且更容易管理,因為 URN 可以引用多個 URL。
2.3 UPnP裝置協議棧
UPnP定義了裝置之間、裝置和控制點、控制點之間通訊的協議。完整的UPnP由裝置定址、裝置發現、裝置描述、裝置控制、事件通知和基於Html的描述介面幾部分構成。UPnP裝置協議棧如下圖所示:
圖2 UPnP協議棧[1]
UPnP協議結構最底層的TCP/IP協議是UPnP協議結構的基礎。IP層用於資料的傳送與接收。對於需要可靠傳送的資訊,使用TCP進行傳送, 反之則使用UDP。UPnP對網路物理裝置沒有要求,可以使用乙太網、無線網、IEEE1394、紅外進行連線, 只要支援IP協議即可。同時UPnP還可以使用TCP/IP協議族中的其他協議, 如ARP、IGMP、DHCP、DNS等。
構建在TCP/IP協議之上的是HTTP協議及其變種,這一部分是UPnP協議的核心部分, 所有UPnP訊息都被封裝在HTTP協議及其變種之中。HTTP協議的變種是HTTPU和HTTPMU, 這些協議的格式沿襲了HTTP協議,只不過與HTTP協議不同的是它們通過UDP而不是TCP來發送訊息,並且可以用於多播通訊。
2.3.1 SSDP協議
簡單服務發現協議(Simple Service Discovery Protocol:SSDP),內建在HTTPU/HTTPMU 裡,定義如何讓網路上有的服務被發現的協議。包括控制點如何發現網路上有哪些服務,並取得這些服務的資訊,還有裝置本身宣告他提供哪些服務。該協議運用在UPnP工作流程的裝置發現部分。
2.3.2 SOAP協議
簡易物件訪問協議(Simple Object Access Protocol:SOAP)定義如何使用XML與HTTP來執行遠端程式呼叫(Remote Procedure Call)。包括控制點如何傳送命令訊息給裝置,及裝置接收到命令訊息後如何傳送響應訊息給控制點。該協議運用在UPnP工作流程的裝置控制部分。
2.3.3 GENA協議
一般事件通知架構(Generic Event Notification Architecture:GENA)定義在控制點想要監聽裝置的某個服務狀態變數的狀況時,控制點如何傳送訂閱訊息並如何接收通知訊息用的。該協議運用在UPnP工作流程的事件訂閱部分。
2.4 基於XML的UPnP描述
2.4.1 XML簡介[2]
XML(Extensible Markup Language)即可擴充套件標記語言,它與HTML一樣,都是SGML(Standard Generalized Markup Language,標準通用標記語言)。XML是Internet環境中跨平臺的,依賴於內容的技術,是當前處理結構化文件資訊的有力工具。擴充套件標記語言XML是一種簡單的資料儲存語言,使用一系列簡單的標記描述資料,而這些標記可以用方便的方式建立,雖然XML佔用的空間比二進位制資料要佔用更多的空間,但XML極其簡單易於掌握和使用。
與HTML類似,XML描述的內容封裝在開始標籤<標籤名>和結束標籤</標籤名>之間,一對標籤及其封裝的內容,如<movie>Gone with the Wind</movie>,被稱為一個元素。元素可以巢狀,一個XML文件正是由許多這樣的元素巢狀而成的。元素可以有屬性,可賦予屬性值。
在實際應用中,人們常常根據需要自定義元素名和屬性名,這些名字具有明確易懂的含義。但是由於應用的繁多,所定義的名字很有可能發生衝突,為此XML引入了名稱空間(namespace)的概念,它給出元素名和屬性名定義的來源處,允許不同應用使用相同的名字,不致引起混淆。
XML名稱空間採用“兩段式命名法”定義所謂的“合法名稱”,例如“學生:姓名”。其中第一段是指代特定名稱空間的“名稱空間字首”,第二段是元素或屬性的名字,兩段之間用西文冒號“:”分隔。需要注意的是,“學生:姓名”和“班主任:姓名”雖然名稱都是“姓名”,但卻是兩個不同的元素名,因為它們分別由“學生”和“班主任”名稱空間定義。
名稱空間用URI標識,具有唯一性和永續性,所謂名稱空間字首就是名稱空間的縮寫表示,XML採用下述“名稱空間宣告"來繫結名稱空間字首和名稱空間:
xmlns:【名稱空間字首】=【名稱空間名】
其中,xmlns就是XML名稱空間的縮寫。例如:
xmlns:學生=http://www.xml.net.cn/學生
xmlns:班主任=http://www.xml.net.cn/班主任
分別定義了名稱空間字首“學生”和“班主任”。
其後,XML就可以用名稱空間和名的組合,即合法名稱來無岐義地表示不同應用中的元素名和/或屬性名,給出元素的描述和屬性值的描述。例如:
<?xml version=”1.0”encoding=”GB23 12”?>
<學生:學生xmlns:學生=http://www.xml.net.cn/學生>
<學生:姓名>李明</學生:姓名>
<學生:班級學生:數字型別=”中文”>三年級二班</學生:班級>
<學生:住址學生:數字型別=”阿拉伯”>135樓210室</學生:住址>
</學生:學生>
上述XML文件描述了關於學生的相關資訊,所採用的元素名和屬性名均源自“學生”名稱空間。上面的描述使用了“學生”名稱空間定義的4個元素名:學生、姓名、班級和住址,1個屬性名:數字型別,並對於“學生:班級”元素的“數字型別”屬性賦予屬性值“中文”,對於“學生:住址"元素的“數字型別"屬性賦予屬性值”阿拉伯”。
類似地,可以用XML文件描述關於班主任的相關資訊,只是需採用“班主任“名稱空間定義的名字。只要不被其他名稱空間宣告所覆蓋,名稱空間宣告對於它所說明的所有元素以及這些元素包含的所有內容都有效,這就是所謂名稱空間的作用域範圍。
2.4.2 TV裝置的裝置描述編寫
在UPnP協議中,要實現控制點和裝置之間的互相通訊,裝置的描述檔案起著很重要的作用。對於裝置的描述檔案,是以XML檔案形式存在的。在論文的第五節,我們會討論TV裝置的程式碼實現,在這我們就對TV裝置的裝置描述檔案編寫進行介紹。
一般來說,裝置描述都是基於UPnP論壇上己定義的模板,這些標準化的模板提供一系列基本的服務和預定義的裝置型別,廠商可以在其中作出自己的擴充。對於後面開發的TV裝置,因為只是為了闡述UPnP協議的實現,所以自行開發其裝置模板及其XML文件,以使其最簡化。
根據UPnP規範,包括兩個主要部分。第一部分包括根裝置型別、特定廠商、製造商資訊,如模組名稱和編號、序列號、製造商名稱、特定廠商網站URL等。第二部分包括裝置所支援服務的資訊。對於第一部分,為了使裝置描述檔案更簡單,為簡單計,省略了廠商名、廠商網址等可選元素,這些省略並不會對系統執行產生任何影響。下面就是TV裝置的裝置描述檔案:
圖3 TV裝置的裝置描述
2.4.2.1 基本資訊編寫
● 裝置型別
裝置型別元素的格式如下:
<deviceType>名稱空間:裝置型別:版本號</deviceType>
對於基於標準裝置模板的裝置,描述檔案中這一屬性為:
<...urn:schemas-upnp-org...>
我們把裝置型別叫做tvdevice,版本號定為1,於是我們得到了一個完整的裝置型別元素:
<deviceType>urn:schemas-upnp-org:device:tvdevice:1</deviceType>
● friendlyname
我們為裝置取了一個相對簡單的使用者友好的別名:UPnP Television Emulator,於是得到了<friendlyname>元素:
<friendlyName>UPnP Television Emulator</friendlyName>
● UDN
接下來需設計的是唯一裝置名字(UDN),這是該例項的唯一識別符號。為了保持唯一性,採用裝置的名字和裝置網絡卡的MAC地址組合而成。假設MAC地址為1234567890001,就可以把UDN元素寫為:
<UDN>uuid:Upnp-TVEmulator-1_0-1234567890001</UDN>
2.4.2.1 裝置服務編寫
裝置所含服務是裝置描述的主體部分,它們體現為裝置的功能。在設計時,可根據裝置的功能對映確定可提供給控制點的服務。在這裡,TV裝置只定義一個control服務。
control服務負責處理TV的開關(power),調整音量(volume)及設定頻道(channel),其在裝置描述文件中的第一個元素是serviceType,其命名原則與deviceType類似,遵從一定的約定,定義為:
<serviceType>urn:schemas-upnp-org:service:tvcontrol:1</serviceType>
類似地,<serviceId>元素定義為:
<serviceId>urn:upnp-org:serviceId:tvcontrol1</serviceId>
另一需要定義的是服務描述文件的地址<SCPDURL>元素,這個元素非常重要,控制點就是通過這個地址來獲取後續的服務描述文件。由於本裝置服務描述文件與裝置描述文件位於同一目錄,名為tvcontrolSCPD.xml,因此該元素為:
<SCPDURL>/tvcontrolSCPD.xml</SCPDURL>
TV控制相關服務最後兩個子元素是控制URL和事件URL。這兩個URL是控制點發送動作請求和訂閱請求的URL。定義為:
<controlURL>/upnp/control/tvcontrol1</controlURL>
<eventSubURL>/upnp/event/tvcontrol1</eventSubURL>
3 UPnP實現的工作流程
圖4 UPnP實現的工作流程
稍微瞭解有哪些通訊協議後,我們來看UPnP是如何運作的。圖4是UPnP的運作流程,我們先介紹各部分在做什麼,再做詳細介紹:
0. 控制點跟裝置都先取得IP地址才能做之後的溝通。
1. 控制點尋找整個網路上的UPnP裝置,而裝置同時也要宣告他本身的存在。
2. 控制點取得裝置的描述,這包括裝置提供什麼樣的服務。
3. 控制點發出動作資訊(對裝置操作的命令資訊)給裝置。
4. 控制點監聽裝置的狀態,當狀態改變時做出相應的處理動作。
5. 控制點利用HTML介面來控制裝置和監看裝置狀態。
3.1 定址(Addressing)
UPnP網路的基礎是TCP/IP協議族,這就決定了每一個UPnP元件(裝置和控制點)必須分配一個IP地址。一個UPnP裝置定址的一般過程是:首先向 DHCP伺服器傳送DHCPDISCOVER訊息,如果在指定的時間內,裝置沒有收到DHCPOFFERS迴應訊息,裝置必須使用 Auto-IP完成IP地址的設定。在選中一個地址之後,裝置測試此地址是否在使用。為了測試選擇的地址是否未被佔用,裝置必須使用地址分辨協議(ARP)。
使用Auto IP的裝置必須定時檢測DHCP伺服器是否存在,若存在,裝置必須釋放Auto IP分配的地址,此時裝置必須取消所有的廣告訊息並重新發出新的。
一個裝置可以使用UPnP之外的更高層的協議,這些協議將為裝置使用友好的名稱。在這種情況下,將這些友好的主機名解析為IP地址就很必要了,DNS通常是用來實現此功能的。使用此功能的裝置可能要包含一個DNS客戶端,而且支援動態的DNS註冊,通過註冊將它自己的名字加入到地址分佈圖中。
3.2 發現(Discovery)
一旦裝置連線到網上並且分配了地址,就要進行發現的操作了。裝置發現是UPnP網路實現的第一步。裝置發現是由簡單發現協議SSDP(Simple Service Discovery Protocol)來定義的。在裝置發現操作之後,控制點可以發現感興趣的裝置,並使得控制點獲得裝置能力的描述,同時控制點也可以向裝置傳送命令,偵聽裝置狀態的改變,並將裝置展示給使用者,即是描述、控制、監聽、展示的基礎。
當一個裝置加入到網路中,裝置發現過程允許裝置向網路上的控制點告知它提供的服務。當一個控制點加入到網路中時,裝置發現過程允許控制點尋找網路上感興趣的裝置。在這兩種情況下,基本的交換資訊就是發現訊息。發現訊息包括裝置的一些特定資訊或者某項服務的資訊,例如它的型別、識別符號、和指向XML裝置描述文件的指標。圖5畫出了發現流程的框架圖。
圖5 發現過程框圖
3.3 描述(Description)
UPnP網路結構的第二步是裝置描述。在控制點發現了一個裝置之後,控制點仍然對裝置知之甚少,控制點可能僅僅知道裝置或服務的UPnP型別,裝置的UUID和裝置描述的URL地址。為了讓控制點更多的瞭解裝置和它的功能或者與裝置互動,控制點必須從發現訊息中得到裝置描述的URL,通過URL取回裝置描述。裝置描述的一般過程如圖6所示:
圖6 獲得裝置描述及服務描述
對於一個裝置的UPnP描述一般分成兩個部分:裝置描述和裝置的服務描述。
●裝置描述
UPnP對某一裝置的描述以XML形式表示出來,裝置描述包括製造商資訊,包括模組名稱和編號,序列號,製造商名稱,製造商網站的URL等等。裝置描述也包括所有嵌入裝置描述和URL地址集。對於一個物理裝置可以包含多個邏輯裝置,多個邏輯裝置既可以是一個根裝置其中嵌入多個裝置,也可以是多個根裝置的方式實現。裝置描述是由裝置製造商提供的,採用XML表述,並且遵循UPnP裝置模版。此模版是由UPnP工作委員會生成的。
● 服務描述
包括一系列命令或者動作,服務響應,動作的引數。服務的描述也包含一系列變數,這些變數描述了服務執行時刻的狀態,這包括資料型別、取值範圍和事件特性的描述。服務描述也是由裝置製造商提供的,採用XML方式表述,遵循UPnP服務模版。
3.4 控制(Control)
在接收裝置和服務描述之後,控制點可以向這些服務發出動作,同時控制點也可以輪詢服務的狀態變數值。發出動作實質上是一種遠端過程呼叫;控制點將動作傳送到裝置服務,在動作完成(或失敗)後,服務返回相應的結果或錯誤。狀態變數值輪詢是這種場景下的特例,動作及其結果都是預定義的。 其基本過程如下圖所示:
圖7 控制點發出動作和輪詢變數
為了控制一個裝置,控制點向裝置服務發出一個動作。這一般由控制點向服務的控制URL地址(在裝置描述的服務元素controlURL子元素部分提供)傳送一個適當的控制訊息。而服務則會對此動作做出響應,返回相關結果或錯誤。動作的效果可以通過改變描述服務執行時狀態的變數進行建模。在這些狀態變數改變時,事件將被髮布到所有相關的控制點。
控制點可能會輪詢服務的狀態變數值以獲得狀態變數的當前值。與發出一個動作的過程相似,控制點向服務的控制URL傳送一個適當的查詢訊息。而服務則返回相應的變數值;每個服務必須保持狀態表的一致性,以便控制點能夠輪詢並接收到有意義的值。
3.5 事件(Eventing)
正如描述部分所述,一個即插即用服務描述包括服務響應的動作列表和執行時描述服務狀態的變數列表。如果一個或多個狀態變數可以被事件觸發,服務將會在這些變數發生變化時釋出更新,控制點可以訂閱以獲得此資訊。通過這一部分,釋出者指事件的來源(通常為裝置服務),訂閱者指事件目的地(通常為控制點)。
圖8 事件過程框圖
如圖8所示,要訂閱事件,訂閱者可傳送一條請求訂閱訊息。如果釋出者收到此訊息,它將以這個訂閱的持續時間作為響應。要保持訂閱,訂閱者必須在訂閱過期之前進行續訂。當訂閱者不再需要釋出者傳送的事件時,訂閱者應當取消其訂閱。
釋出者通過傳送事件訊息提醒訂閱者狀態變數改變。事件訊息包含多個狀態變數名稱和這些變數的當前值,以XML表示。在訂閱者第一次訂閱時,需要傳送一個專門的初始化事件訊息。該事件訊息包含所有事件變數的名稱和值,並且允許訂閱者初始化其服務狀態模型。為了支援多個控制點,在動作生效後所有訂閱者均會收到通知。由此,將向所有訂閱者傳送全部事件訊息,訂閱者會收到所有事件觸發變數的事件訊息(不只是一部分)。不管狀態變數因何種原因發生改變(無論為了響應所要求的動作,還是由於服務模擬的狀態發生變化)均會發送事件訊息。 事件訊息使用HTTP協議傳送,事件詳細定義在通用事件通知結構(General Event Notification Architecture)協議中。
3.6 展示(Presentation)
在控制點發現裝置和取得裝置描述之後,控制點即準備開始提供展示。如果裝置擁有進行展示的URL,那麼控制點就可以通過此URL取得一個頁面,在瀏覽器中載入該頁面,並根據頁面功能,支援使用者控制裝置和/或瀏覽裝置狀態。每一項完成的程度取決於展示頁面和裝置的具體功能。
裝置表徵包含在裝置描述的presentationURL欄位。裝置表徵可以完全由裝置製造商提供,它採用HTML頁的形式,使用HTTP進行釋出。圖9畫出了展示流程的示意圖。
圖9 展示(Presentation)示意圖
4 基於Linux的UPnP協議實現的原始碼模組
為了促進UPnP協議的發展,資訊業巨頭Intel公司開放了一個基於Linux的UPnP協議棧原始碼,該協議棧實現了UPnP規範中SSDP協議模組,GENA協議模組,SOAP協議模組。本文後面列舉的TV控制點和裝置的原始碼實現就是基於這個開源協議棧。本部分將對該協議棧模組的體系結構做簡單分析,其協議模組的體系結構如圖10所示。
圖10 UPnP協議實現的各個模組[1]
4.1 裝置/控制點
客戶端或伺服器的申請軟體均執行在軟體開發包(SDK)之上。客戶端或伺服器的申請相當於執行了一個完成特殊服務的函式。例如,拿一個閘道器服務來說,伺服器軟體執行這個“Enable Internet”函式時,就相當於控制點軟體開始能控制使用UPnP裝置。
4.2 UPnP軟體開發包API(UPnP SDK API)
UPnP軟體開發包API部分將UPnP協議核的詳細內容從控制點和伺服器申請中抽象如來,並且給了一個統一介面的入口函式,裡面包含了SSDP,GENA和SOAP等協議。
這個API層也包含了用軟體開發包(SDK)註冊的控制點和裝置操作列表。每個對API函式的請求,軟體開發包(SDK)都將會對照操作列表中的相應項,對操作列表中所包含的相應操作,在這裡均會使之生效。同時,在這個過程中,只限對一個控制點或一個裝置的操作進行定位。換句話說,一個申請一次要麼註冊一個裝置,要麼註冊一個控制點,而一個申請不能同時註冊一個裝置和控制點。任何想同時註冊裝置和控制點的申請都會失敗。
4.3 WEB Server
微型伺服器模組處理一個標準的HTTP GET請求。在UPnP組成元素中,都要求使用基本的HTTP服務,所以需要使用微型伺服器模組來完成基本的HTTP服務。微型伺服器模組管理文件的定位,這些文件一般對GET命令有效,並且執行使用HTTP協議的資料流進行傳輸。
微型伺服器也支援虛擬路徑HTTP POST請求,但不支援其他種類的請求。
4.4 庫模組
4.4.1 XML解析模組
XML在UPnP中被廣泛地使用。描述文件就是XML文件。GENA使用XML來描述一個服務狀態的描述變化。SOAP使用XML來格式化請求和響應。軟體開發包(SDK)包含一個XML解析,這個XML解析會被UPnP協議核和客戶端或服務端軟體使用。
4.4.2 SDK中的執行緒庫
UPnP協議棧的實現中大量採用了多執行緒技術,該模組就是為了更方便高效地使用執行緒技術,其中包含了一個定時器執行緒子模組和一個執行緒池子模組。執行緒池子模組用於管理協議棧中所有的執行緒;定時器執行緒子模組用來處理協議棧中所有的定時事件。
應用層在呼叫API UpnpInit()時會初始化兩個緩衝池(由ThreadPoollnit()建立):傳送緩衝池,接收緩衝池。在建立每個緩衝池時都要給定一個緩衝池的屬性作為引數,以確定在該緩衝池中最少,最多可以容納的執行緒數,然後呼叫CreateWorker()建立所需的執行緒。
當有新的任務要執行的時候,呼叫TPJobInit(),ThreadPooIAddPersistent()或者ThreadPoolAdd()將任務加到緩衝池的相應佇列中,等待空閒的執行緒呼叫執行。
4.4.3 HTTP解析器
裝置公告訊息、裝置查詢訊息、裝置查詢響應訊息都是用HTTP協議來封裝的,使用了SSDP協議定義的頭和方法,這需要開發者自己來解釋這些訊息。同樣,事件訂閱訊息和事件取消訂閱訊息也是用HTTP協議來封裝的,使用了GENA定義的頭和方法,也需要開發者自己解析這些訊息.這裡我們把這兩部分的HTTP訊息解析合併成一個模組:HTTP訊息的解析。通常的HTTP訊息是由瀏覽器或www伺服器來解析的,這裡的HTTP訊息解析只對SSDP、GENA定義的特殊的HTTP訊息進行解析。
4.4.4 微型伺服器(Mini Server)
Mini Server層提供GENA、SOAP、SSDP、mini web server需要的公共功能,這一層接收所有的網路連線,並決定哪個請求可以進入上層,將HTTP頭部交給HTTP模組去解析,並將這個連線轉向合適的協議去處理。
5 TV控制點及裝置的程式碼實現
本部分採用一個例項對UPnP的程式碼實現進行了闡述,該例子中包括一個TV控制點和一個TV裝置,且只實現控制點對電視裝置的搜尋,無法搜尋其他的UPnP裝置。該例實現了對TV裝置的服務控制及服務訂閱等流程。工作平臺為Windows XP,編譯環境為Visual Studio2008,使用兩臺PC,一臺PC上執行TV控制點,一臺PC執行TV裝置,且兩臺PC處於同一區域網中,操作結果在各自的執行介面上顯示。
5.1 TV控制點的程式碼實現
5.1.1發現、描述的程式碼實現
圖11 發現裝置及獲得裝置描述的實現流程圖
發現、描述流程的實現流程圖如圖11所示,需要說明的是,本例的發現請求訊息沒有收到TV裝置的直接響應,因為考慮到本例只實現對一個TV裝置的搜尋,所以只需要解析TV裝置傳送的廣播訊息就足以獲得裝置的描述檔案等。
5.1.1.1 啟動及初始化
● UpnpInit()初始化SDK
應用程式可以在初始化過程中指定IP地址和埠號。對於控制點來說,設定IP地址和埠號用於監聽事件訊息。如果地址為空,那麼第一個非空、非迴路地址將被使用。你可以在初始化完成後通過UpnpGetServerlpAddress0和UpnpGetServerPort()來取得IP地址和埠號。TV控制點就是這樣來實現的。
在UpnpInit()函式裡,建立了傳送執行緒池和接收執行緒池,並啟動miniserver。
● UpnpRegisterClient()註冊控制點
對於函式UpnpRegisterClient(),第一個引數是控制點希望SDK使用的回撥函式。TV例子中是TvCtrlPointCallbackEventHandler()。第二個引數是指向一小段資訊的指標,這段資訊在回撥函式被觸發時會傳遞給回撥函式。TV例子中傳遞的是控制點控制代碼。最後一個引數是指向控制點控制代碼的指標,這個控制代碼在生成後續SDK呼叫時會用到。
TV例子使用TvCtrlPointCallbackEventHandler0處理所有非同步操作,該函式處理所有的事件訊息,包括SSDP,GENA,SOAP等。後續討論在必要時會述及該函式的某些片斷。
在控制點呼叫UpnpRegisterClient()註冊回撥函式後,所有網路上裝置的裝置宣告訊息將會由回撥函式傳遞給應用程式。應用程式應該準備好處理這些訊息。
5.1.1.2 發現裝置
當控制點應用程式初始化完成後,就可以開始在網路上搜索感興趣的裝置。TV例子是一個非常簡單的控制點,它只搜尋一種裝置:Tv例子裝置。
● UpnpSearchAsync()函式發現裝置
例子在函式TvCtrlPointRefresh()開始搜尋TV裝置。UpnpSearchAsync()開始搜尋裝置過程。它有以下引數:
·控制點控制代碼
·控制點等待響應的時間(以秒為單位,程式裡為5)
·搜尋目標
·一段可選的cookie
對於TV裝置而言,搜尋目標定義為:
char TvDeviceType[]=”urn:schemas-upnp—org:device:tvdevice:1”;
● readFromSSDPSocket()接收SSDP廣播訊息並進行處理
在該函式裡會啟用一個事件處理執行緒ssdp_event_handler_thread,在該執行緒裡會對來自裝置的廣播訊息會由函式ssdp_handle_ctrlpt_msg()進行處理,然後將相應引數送到TvCtrlPointCallbackEventHandler()函式進行處理,從而獲得裝置描述檔案。
● TvCtrlPointCallbackEventHandler()函式處理所有事件資訊
函式原型如下:
int CallbackFxn(Upnp_EventType EventType,void *Event, void *Cookie);
其中第一個和第二個引數均由UPnP模組在發生回撥時傳入,EventType表徵了待處理的UPnP請求的型別,Event是指向一個結構體的指標,該結構體中包含了關於請求訊息的具體資訊,不同型別的請求會對應不同的結構。引數Cookie是裝置應用程式中定義的資料。
● 發現事件訊息結構體
當控制點收到來自裝置的響應訊息後,會經由miniserver相應處理,傳給回撥函式一個發現事件訊息,其結構體如下:
該結構體裡面返回了很多關於裝置的重要資訊,包括裝置型別(tvdevice)、服務型別(tvcontrol)、以及裝置描述檔案的URL位址等等。
5.1.1.3 獲得裝置描述
● UpnpDownloadUrlItem()獲得裝置描述XML資料
在該函式裡,通過裝置URL建立裝置描述請求訊息,再經過傳送並等待響應訊息,在響應訊息裡獲得裝置描述XML資料存在一個char* buffer裡。
● ixmlParseBufferEx()函式解析XML文件(首行縮排2字元)
在上述函式獲得XML資料後,呼叫該函式對其進行解析,解析的作用是將XML檔案資料解析成DOMtree結構,從而可對裝置描述檔案進行訪問。
5.1.2 訂閱服務的程式碼實現
圖12 訂閱的程式碼實現流程圖
5.1.2.1 訂閱
● SampleUtil_FindAndParseService()獲取服務的URL
int SampleUtil_FindAndParseService( IN IXML_Document * DescDoc,
IN char *location,
IN char *serviceType,
OUT char **serviceId,
OUT char **eventURL,
OUT char **controlURL )
第一個引數為以XML檔案存在的裝置描述檔案,第二個是裝置描述檔案的URL,第三個是服務型別,後面三個分別是函式執行後得到的該服務的SID,事件URL和控制URL。
● gena_subscribe()完成訂閱任務
通過上述函式得到事件URL後,就可以開始訂閱任務了。訂閱函式為:
gena_subscribe( IN char *url, INOUT int *timeout,
IN char *renewal_sid, OUT char **sid )
url:訂閱的服務URL;
timeout:訂閱的截至時間;
renewal_sid:用於續訂,對於第一次訂閱,此指標為空;
sid:函式返回一個用於訂閱該服務的訂閱標誌符SID,續訂會用到;
從上述引數可知,訂閱一個服務,主要是通過服務的URL位址來實現。對於裝置,會返回一個用於此服務訂閱的SID,用於釋出事件訊息和續訂等。
● 回撥函式處理的事件訊息結構體
在控制點訂閱了某服務後,裝置就會立即返回一個事件通知訊息,反映該服務的狀態變數及其當前值,其返回的事件訊息經GENA模組處理後,會得到一個由回撥函式處理的事件結構體,如下:
5.1.2.2 續訂
● genaRenewSubscription()完成續訂任務
實現任務的續訂,是通過函式ScheduleGenaAutoRenew()在gTimerThread執行緒池裡建立一個自動續訂任務,最後通過函式genaRenewSubscription()來實現的。
int genaRenewSubscription( IN UpnpClient_Handle client_handle,
IN const Upnp_SID in_sid,
INOUT int *TimeOut )
client_handle: 控制點控制代碼。
in_sid: 訂閱標誌符SID(在第一次訂閱時獲得)。
TimeOut:續訂的持續時間
由上述引數可知,完成續訂任務並不是通過服務的URL位址,而是通過在第一次訂閱時取得的SID來實現的。
5.1.3 控制服務的程式碼實現
圖13 控制程式碼實現流程圖
5.1.3.1 動作呼叫的程式碼實現
● UpnpMakeAction()建立動作請求訊息
在向裝置傳送動作訊息的函式要用到描述動作的DOM檔案,SDK中有組織這些DOM檔案的功能函式:UpnpMakeAction()和UpnpAddToAction0。TV例子中在TvCtrlPointSendAction0充分利用了這些函式:
如果動作不需要引數,UpnpMakeAction()就已經足夠構造正確的動作節點了。否則的話,將會反覆呼叫UpnpAddToAction()往動作節點檔案中新增引數。
● UpnpSendActionAsync()傳送動作訊息
控制點通過改變裝置的內部狀態來使裝置完成某些功能。這是通過向裝置傳送動作訊息實現的。SDK有兩個函式用於改變裝置的內部狀態:UpnpSendAction()和UpnpSendActionAsync()。兩個函式都完成相同的功能,只是後面一個是非同步操作。
第一個引數為控制點控制代碼,第二個為被控制的服務型別,第三個是服務的控制URL,第四個引數是裝置的UDN,此處為空;第五個是以XML文件形式存在的動作請求訊息;第六個是動作完成後的回撥函式,最後一個是存放使用者資料的可選項,此處為空。
當非同步的動作訊息傳送完成後,響應訊息通過回撥函式返回,回撥函式控制代碼是由UpnpSendActionAsync()指定或由UpnpRegisterClient()註冊,例子中傾向於對所有的訊息用同一個控制代碼,所有動作完成和服務狀態變數查詢訊息均在TvCtrlPointCallbackEventHandler()結束。
5.1.3.2 查詢變數的程式碼實現
● UpnpGetServiceVarStatusAsync()查詢狀態變數
另外,要查詢服務的某個狀態便量的值也可以通過兩個函式來實現:UpnpGetServiceVarStatusAsync()和UpnpGetServiceVarStatus()。兩個函式都完成相同的功能,只是前一個是非同步操作。
對於函式UpnpGetServiceVarStatusAsync(),和函式UpnpSendActionAsync()的引數基本上一致,最大的不同是請求查詢變數不是以XML文件形式存在,而是以char型,具體的封裝成XMl文件形式是在函式內部解決的。
當非同步的查詢請求訊息傳送完成後,和前面的動作請求一樣,響應訊息通過回撥函式返回。
5.1.4 退出
當控制點應用程式退出時,需要用UpnpUnRegisterClient0 SDK取消註冊並用UpnpDeInit0關閉SDK。
5.2 TV裝置的程式碼實現
圖14 TV裝置實現流程圖
5.2.1 設定和初始化裝置
● 初始化UPnP協議棧
與控制點一樣,初始化庫方法是呼叫庫函式Upnplnit()。
● 設定根目錄
初始化UPnP協議棧後,有必要為UPnP模組中的web Server指定根目錄,這樣當網路中的控制點向伺服器發出請求各種裝置或服務描述檔案資源的話,web server將在該目錄下搜尋。這一步通過UpnpSetWebServerRootDir()完成。
● 註冊根裝置
通過這一步,TV裝置與UPnP庫關聯在一起。當miniserver伺服器監聽到有對應與TV裝置的請求時,將回調該裝置提供回撥事件處理函式進行處理。其程式碼片段如下:
UpnpRegisterRootDevice()的第一個引數為裝置描述檔案的URL;第二個引數為裝置的回撥事件處理函式,為TvDeviceCallbackEventHandler()。該函式是UPnP裝置的核心。最後一個引數用於接收UPnP模組為裝置分配的控制代碼,通過該控制代碼可以操作裝置。
● 特定裝置的初始化
在向網路宣告裝置之前,還需要做一些特定於裝置的初始化工作,比如:對巢狀於裝置中的服務的狀態變數的初始化。
● 宣告裝置
完成上述步驟後,向網路上的控制點宣告裝置的存在。程式碼如下;
至此,裝置開始等待請求訊息的到來,進入事件處理迴圈。
5.2.2 處理非同步請求
裝置的生命期中,最主要的任務就是處理由控制點發送過來的各種非同步請求。UPnP裝置在生命期內需要處理的非同步請求可分三類:訂閱請求,取值請求和操作請求。
5.2.2.1 訂閱請求處理
該請求用於訂閱UPnP裝置中巢狀服務的狀態改變事件通知。當控制點向UPnP裝置傳送訂閱請求時,處於監聽狀態miniserver伺服器激發裝置應用中定義的回撥函式,該回調函式將在一個獨立的執行緒中執行。而傳入回撥函式的EventType引數值為UPnP模組中定義的型別常量UFNP_EVENT_SUBSCRIFTION_REQUEST;引數Event指向的包含具體請求資料的結構體型別為Upnp_Subscription_Request,其定義如下:
在請求的後續處理中將呼叫UpnpAcceptSubscription()或者UpnpAcceptSubscriptionExt()來響應控制點,這兩個函式的區別在於兩者以不同的方式傳送服務狀態表給UPnP模組,前者使用對應的“變數”“變數值”陣列方式,後者使用DOM文件,訂閱請求成功之後,每當控制點訂閱的UPnP裝置的服務狀態發生變化,它都會被及時通知。
5.2.2.2 取值請求處理
該請求用於返回指定的UPnP裝置巢狀服務中的服務狀態變數當前值。UPnP裝置監聽到控制點的取值請求後,啟用裝置中預定義的事件處理回撥函式,傳入的引數EventType值為UPNP_CONTROL GET_VAR_REQUEST,而引數Event則指向一個Upnp_State_Var_Request型別的結構體,其定義如下:
裝置對該請求的響應就是在Event指向的結構體的變數當前值域填入所求變數的當前值,然後返回,讓miniserver模組提供的介面傳送響應給控制點。
5.2.2.3 操作請求處理
操作請求用於改變指定的UPnP裝置巢狀服務中的服務狀態變數。當UPnP裝置收到操作請求時,裝置應用中定義的回撥函式將被呼叫,傳入的引數EventType值為UPNP_CONTROL_ACTION_REQUEST,而引數Event指標則指向一個Upnp_Action_Request型別的結構體,下面是此結構體的型別宣告:
TV裝置將從操作請求文件中提取出完成操作所需的相關引數,執行請求操作,並建立一個響應文件(該文件內含有可能的操作出口引數),最後傳送事件,通知控制點裝置的服務狀態已經改變。
5.2.3 傳送事件通知
當裝置中某一服務的狀態變數改變時,裝置需要傳送對應的更新事件給網路中已訂閱這些狀態變數的控制點,可通過呼叫UpnpNotify()完成事件通知。
5.2.4 關閉裝置
當裝置被關閉時,先要向網路中的各控制點發送SSDP“bye-bye”訊息,宣告裝置將不再可用。同時釋放所佔用的資源,下面兩條語句完成這一任務。
UpnpUnRegisterRootDevice( device_handle ) ;
UpnpFinishO;
函式UpnpUnRegisterRootDevice()的引數為裝置控制代碼。
6 UPnP協議訊息分析
6.1 發現裝置的訊息分析
UPnP協議的發現過程是通過SSDP協議來實現的,SSDP訊息至少包含以下四部分:
·服務型別URI
用來標識一種服務,如宣告訊息中的NT欄位,搜尋訊息中的ST欄位。
·唯一的服務名字(USN)URI
USN用來區分同一服務型別的不同的具體服務。
·有效期資訊
指明SSDP客戶在其快取中儲存該服務資訊的時間,如宣告訊息中的
CACHE.CONTROL欄位。
·位置資訊
服務所在位置,如宣告訊息中的LOCATION欄位。
6.1.1 SSDP發現請求
SSDP發現請求用來尋找希望得到的裝置及其服務。它使用SEARCH訊息,用URI ssdp:discover標識。SEARCH訊息必須包括一個ST(搜尋型別)頭,還可能含有訊息體。ST頭用來指明希望發現的裝置及服務型別。目前只指定了在多播UDP中使用該請求,以後可能擴充套件到TCP。
只有那些與ST匹配的服務才可能通過SSDP埠給出響應,響應應該在AL頭中表示出服務的地址,同時,響應中還要包括快取控制資訊:有效期。沒有快取控制資訊的響應將被視作無效響應。由4.1.1知,本例沒有裝置的響應訊息。
以下是TV控制點發出的發現裝置請求訊息:
圖15 TV控制點發送的請求發現裝置訊息
從ST頭可以知道,TV控制點搜尋的裝置是tvdevice,裝置號為1。其中HOST由網際網路編號分配組織(IANA)為SSDP保留的多播通道和埠。必須是239.255.255.250:1900。MAN是強制擴充套件宣告標頭,一個含有強制擴充套件宣告的HTTP請求被稱作強制請求,在這個訊息中使用強制擴充套件的用意在於確定接受方是否理解和支援ssdp:discover,接受方如果支援ssdp:discover,將會對擴充套件宣告進行解析,否則返回出錯資訊。
6.1.2 SSDP存在宣告
SSDP存在宣告可以讓SSDP客戶知道裝置及服務的存在、更新快取中的過期資訊、服務的位置改變或即將無效。SSDP存在宣告使用NOTIFY訊息,NOTIFY訊息包括位置和/或AL頭部(指示裝置及服務的地址)、NT頭(指示裝置及服務型別)、USN(唯一服務名稱,可以和其它同類型服務相區別)以及Cache-Control或者Expiration頭部(快取控制資訊)。對方收到後根據NOTIFY的NT判定是否是自己感興趣的裝置及服務。如果是,若快取中未見此USN,則增加記錄,否則更新記錄。對此訊息不需要給出響應。
圖16 TV裝置傳送的宣告訊息
從NT頭知道,TV裝置是根裝置,由NTS子型別知道,該裝置目前可用,且由USN指出了TV裝置的唯一裝置名稱UUID。
6.2 描述資料包分析
一般情況而言,在描述部分,控制點會得到兩類描述,裝置描述和服務描述,本例只獲得了裝置描述。因為TV裝置只定義了一個服務,其變數為power、channel、volume。這三個變數直接是通過在程式碼裡定義,然後進行操作的。
6.2.1 獲取裝置描述的請求訊息
圖17 控制點發送的GET請求訊息
控制點是通過傳送HTTP GET訊息來請求獲得裝置描述的。GET指出了裝置描述的路徑,此處為裝置描述URL(發現訊息中的LOCATION標頭);HOST指出了裝置描述URL的域名或IP地址及可選埠部分。
6.2.2 TV裝置的裝置描述訊息
圖18 裝置返回的裝置描述訊息
空白處前面的資料為HTTP訊息頭,描述了XML描述檔案的一些基本資訊,空白處下面的資料就為XML檔案的具體內容,具體的引數內容詳見圖3。
6.3 事件資料包分析
6.3.1 訂閱請求的訊息分析
對於裝置中的每項服務,描述訊息均包含一個事件觸發URL(裝置描述中服務元素的eventSubURL子元素)和UPnP服務識別符號(裝置描述中服務元素的serviceId子元素)。為訂閱特定服務的事件,訂閱訊息將被髮送到該服務的事件觸發URL。(注意,事件觸發URL可能相對於基本URL。)訊息中含該服務的識別符號以及事件訊息交付URL。訂閱訊息還可能包含所要求的訂閱持續時間。
圖19 訂閱訊息
由上圖可知,本訂閱訊息訂閱的是TV的control服務,CALLBACK指出了回送的路徑,即TV控制點的IP和埠,NT指出了TV控制點想接受的事件訊息,HOST指出了事件觸發URL(裝置描述中服務元素的eventSubURL子元素)的域名或IP地址和可選埠元件。TIMEOUT指出了直到訂閱期滿所要求的持續時間。
圖20 訂閱的響應訊息
由上圖知,響應訊息返回了一個用於本次訂閱的訂閱號SID,此SID在訂閱期間必須是唯一的。DATE指出了響應生成的具體時間。
6.3.2 續訂請求的訊息分析
為續訂特定服務的事件,續訂訊息將被髮往該服務的事件觸發URL。然而,與最初的訂閱訊息不同,續訂訊息既不包含服務識別符號也不包含事件訊息交付URL,而是包含由釋出者(裝置)分配的訂閱識別符號,為續訂提供明確的參考。與訂閱訊息相同,續訂訊息還可能包含所要求的訂閱持續時間。
圖21 續訂請求資料包
由上圖知,TV控制點直接通過SID完成對tvcontrol的續訂任務。
6.3.3 NOTIFY事件通知訊息分析
當裝置的服務狀態變數有變更時,裝置會發布其狀態變數變更的事件訊息。對於控制點而言,在完成訂閱或者續訂了某項服務之後,它就會收到關於此服務的狀態變數變更的事件訊息。
以下是裝置傳送的關於tvcontrol的事件通知訊息。
圖22 裝置返回的tvcontrol服務的事件通知資訊
在空白處上方是事件訊息的命令列和標頭。標頭裡的SEQ是事件編號,對於事件訊息均標有事件編號,為便於進行錯誤檢查,釋出者必須保持每個訂閱有一個單獨的事件編號。當釋出者傳送初始化事件訊息時,訂閱事件編號被初始化為0(圖 22所示的便是這種情況)。對於以後的每條事件訊息,釋出者會增加訂閱事件編號,包括事件訊息更新的編號。
空白處下方是該事件訊息的訊息體部分,以XML文件形式存在。在訊息體內,指出了關於tvcontrol服務的所有狀態變數(Power、Channel、Volume)及其當前值。
6.4 控制資料包分析
6.4.1 動作呼叫的訊息分析
● SOAP動作呼叫
簡單物件訪問協議(SOAP)定義使用XML和HTTP的遠端過程呼叫。UPnP使用SOAP來向裝置提供控制訊息,並將結果或錯誤返回控制點。
為了向裝置的服務發出一個動作,控制點必須採用以下格式的POST方法傳送一個請求。以下是TV控制點向TV裝置傳送的SOAP控制訊息(以PowerOn為例):
圖23 請求資料包和響應資料包
前一部分是控制點發送的控制請求訊息,採用POST方法,訊息體為XML檔案形式。在標頭部分,HOST指出了控制此服務的域名或IP地址、以及URL可選埠元件(裝置描述服務元素的controlURL子元素);SOAPACTION 是SOAP協議規定使用的標頭,由呼叫的服務型別、雜湊符號和動作名稱組成,均用雙引號括起來,PowerOn為要傳送的動作名稱。在訊息體部分,Envelope的“http://schemas.xmlsoap.org/soap/envelope”用來表示SOAP使用了HTTP擴充套件框架;Body指出了具體的控制動作(PowerOn)。
後一部分是TV裝置回送的響應訊息,同樣訊息體以XML檔案形式回覆,回覆訊息表明了Power在動作執行後的當前值。在標頭部分,DATE指出了響應生成的具體時間;在訊息體的BODY部分,裝置返回了被操作的服務狀態變數(Power)在執行動作(PowerOn)後的當前值。
● 事件通知的訊息分析
在控制點發送的動作訊息,裝置執行了之後,除了傳送相應的響應訊息,裝置還會採用GENA協議傳送一個事件通知訊息給控制點,該訊息會經由miniserver模組處理,然後由回撥函式TvCtrlPointCallbackEventHandler()更新相應的狀態變量表。
圖24 動作執行後的通知訊息資料包
在資料包的訊息體部分,返回了Power服務變數的當前值為1,即PowerOn的狀態。
6.4.2 查詢變數的訊息分析
除了向裝置的服務發出動作,控制點還可以對服務進行輪詢,以通過傳送查詢訊息獲得狀態變數值。查詢訊息只能查詢一個狀態變數,必須傳送多個查詢訊息以查詢多個狀態變數。 此查詢訊息與該服務的事件(如果有)相分離。以下是TV例子所傳送的查詢訊息和響應訊息:
圖25 查詢資料包
與前面的動作呼叫一樣,前一部分是傳送的查詢請求訊息,在標頭部分,SOAPACTION中的QueryStateVariable表明是查詢資訊,這與動作呼叫區分開來;在訊息體的BODY部分,指明瞭查詢的服務狀態變數(Power)及其所在的服務(control)。
後一部分是TV裝置返回的響應訊息,在訊息體的BODY部分,返回了服務狀態變數Power的當前值為1。
結論
作為家庭網路的核心技術之一,UPnP充分重用網際網路技術標準,提供服務的跨平臺自動發現和遠端控制。基於UPnP技術設計應用程式將非常簡單,目前許多國家在制訂家庭網路體系結構時都採用了該項技術,因此UPnP有良好的應用前景,有必要積極研究開發基於UPnP的裝置和應用。
論文系統地研究了UPnP及其相關協議,並結合TV控制點和裝置的模擬實現,從規範描述和裝置開發兩個方面深入研究UPnP的實現技術。論文最後對捕獲的資料包進行了詳盡分析,為開發過程中的相關資訊查詢提供了有力參考,且為UPnP裝置開發提供了事例借鑑。
當然,UPnP技術的普及任重道遠,從技術層面來講,尚有許多工作需要做。例如,需要對更多的資訊裝置制定UPnP標準規範;需根據規範描述開發更多的UPnP裝置產品;還有必要進一步研究UPnP技術與OSGI、Jini等技術之間的聯絡,以實現真正的家庭聯網。
[1] UPnP Forum,About UPnP[EB].http://www.UPnP.org。
[2] W3C. Extensible Markup Language (XML)[EB]. http://www.w3.org/XML/, 2010/03/14。
[3] 肖繼民. 基於UPnP 的家庭網路技術及實現研究[D]. 南京:南京郵電大學[碩士學位論文],2007.3。
[4] 王政軍. 基於Intel UPnP SDK的UPnP協議程式設計[EB]. http://www.cqvip.com/qk/92317A/200507/18013100.html, 2007-3-18。
[5] 沈彬斌.UPnP中介軟體技術在數字家庭網路中的應用研究[D].成都:電子科技大學[碩士
學位論文],2006.02。
本文是在杜鴻老師的熱情關心和指導下完成的,他淵博的知識和嚴謹的治學態度使我受益匪淺,對順利完成本課題起到了極大的作用。在此向他表示我最衷心的感謝!
在論文完成過程中,本人還得到了劉暢老師和羅貞蘭同學的熱心幫助,本人向他們表示深深的謝意!
最後向在百忙之中評審本文的各位專家、老師表示衷心的感謝!
作者簡介:
姓 名:蔡鳳梅 性別:女
出生年月:1987.01 民族: 漢
E-mail:[email protected]
相關推薦
基於DLNA的UPNP協議的分析及實現
1 引言 UPnP 全名是Universal Plug and Play,主要是微軟在推行的一個標準。簡單的來說,UPnP 最大的願景就是希望任何裝置只要一接上網路,所有在網路上的裝置馬上就能知道有新裝置加入,這些裝置彼此之間能互相溝通,更能直接使用或控制它,一切都不需要設定,完全的Plug and Pla
Linux網路程式設計---ICMP協議分析及ping程式實現
一、IP協議 IP協議是TCP/IP協議族所依賴的傳送機制,提供無連線不可靠的資料報服務。IP的無連線特性意味著每個IP報文都是獨立尋徑的,因此當一個源主機發送多個報文給同一目的主機時,這些報文可能出現錯序,丟失或者部分報文產生錯誤等現象,因此為了保證資料傳送的可靠性,必須
信息摘要算法之二:SHA1算法分析及實現
專家 臨時 總結 tro sha-1 即使 img md4 stand SHA算法,即安全散列算法(Secure Hash Algorithm)是一種與MD5同源的數據加密算法,該算法經過加密專家多年來的發展和改進已日益完善,現在已成為公認的最安全的散列算法之一,並被廣泛使
RabbitMQ可用性分析及實現
RabbitMQ實戰:可用性分析和實現,場景可以使用「發後即忘」的模式,不需要響應,如果需要響應,可以使用RabbitMQ的RPC模型。 RabbitMQ以非同步的方式解耦系統間的關係,呼叫者將業務請求傳送到Rabbit伺服器,就可以返回了,Rabbit會確保請求被正確處理,即使遇到網路異常、R
LinkedHashMap原始碼分析及實現LRU演算法
PS: 要先了解HashMap的實現原理HashMap原始碼分析 一、簡單介紹 public class LinkedHashMap<K,V> extends HashMap<K,V> implements Map<K,V>
B樹的原理分析及實現
B樹是為磁碟或其他直接存取的輔助裝置而設計的一種平衡搜尋樹。許多資料庫系統使用B樹或B樹的變種來儲存資訊。為何會採用這種樹結構進行設計呢,《演算法導論》18章講得很到位,值得細細品味。 下面直接開始瞭解B樹的實現細節吧! 一、B樹的定義 它與二
二項佇列分析及實現
定義: 二項佇列不同於左式堆和二叉堆等優先佇列的實現之處在於,一個二項佇列不是一棵堆序的樹,而是堆序樹的集合,即森林。堆序樹中的每棵樹都是由約束形式的,叫做二項樹。每一個高度上至多存在一棵二項樹。高度為0的二項樹是一顆單節點樹,高度為k的二項樹Bk通過將一棵二項樹B
RTMP協議分析及推流過程
簡介: 1.RTMP(實時訊息傳輸協議)是Adobe 公司開發的一個基於TCP的應用層協議。 2.RTMP協議中基本的資料單元稱為訊息(Message)。 3.當RTMP協議在網際網路中傳輸資料的時候,訊息會被拆分成更小的單元,稱為訊息塊(Chunk)。 RTMP 握手(
密碼強度檢測演算法分析及實現(JavaScript)案例說明
用正則表示式做使用者密碼強度的通過性判定,過於簡單粗暴,不但使用者體驗差,而且使用者帳號安全性也差。那麼如何準確評價使用者密碼的強度,保護使用者帳號安全呢?本文分析介紹了幾種基於規則評分的密碼強度檢測演算法,並給出了相應的演示程式。大家可以根據自己專案安全性需要,做最適合於自
網路協議分析與實現簡單概念
通訊協議 是指雙方實體完成通訊或服務所必須遵循的規則和約定。 協議的基本內容 語義:協議所要表達的核心含義; 語法:語義能夠正確表達的規範; 時序:語義被正確表達的時間點和先後順序。 OSI七層模型: 應用層:使用者介面; 表示層:資料表
資料結構--二項佇列分析及實現
一,介紹 什麼是二項佇列,為什麼會用到二項佇列? 與二叉堆一樣,二項佇列也是優先順序佇列的一種實現方式。在 資料結構--堆的實現之深入分析 的末尾 ,簡單地比較了一下二叉堆與二項佇列。 對於二項佇列而言,它可以彌補二叉堆的不足:merge操作的時間複雜度為O(N)。二項佇列的merge操作的最壞時間複雜
Kademlia Emule協議分析及和Bt協議的比較
Kademlia 是個 Petar Maymounkov 與 David Mazières 所設計的點對點 (P2P) 重疊網路傳輸協議,以達成非集中式的點對點 (P2P) 電腦網路。它規制了網路的結構及規範了節點間的通訊和交換資訊的方式。Kademlia 節點間使用傳輸通訊
微信網頁版協議分析和實現機器人
開啟首頁,分配一個隨機uuid,根據該uuid獲取二維碼圖片。微信客戶端掃描該圖片,在客戶端確認登入。瀏覽器不停的呼叫一個介面,如果返回登入成功,則呼叫登入介面此時可以獲取聯絡人列表,可以傳送訊息。然後不斷呼叫同步介面。如果同步介面有返回,則可以獲取新訊息,然後繼續呼叫同步介面。Java版實現原始碼:htt
Socket通用TCP通訊協議設計及實現(防止粘包,可移植,可靠)
Socket通用TCP通訊協議設計及實現(防止粘包,可移植,可靠) 引文 我們接收Socket位元組流資料一般都會定義一個數據包協議。我們每次開發一個軟體的通訊模組時,儘管具體的資料內容是不盡相同的,但是大體上的框架,以及常用的一些函式比如轉碼,校驗等等都是相似甚至一樣的
rtmp 協議分析及互動過程
本文描述了從開啟一個RTMP流媒體到視音訊資料開始播放的全過程。 注意:RTMP中的邏輯結構 RTMP協議規定,播放一個流媒體有兩個前提步驟:第一步,建立一個網路連線(NetConnection);第二步,建立一個網路流(NetStream)。其中,網路連線代表伺服器端應用程式和客戶端之間基礎的連通
RTMP協議分析及H.264打包原理
RTMP是Real Time Messaging Protocol(實時訊息傳輸協議)的首字母縮寫。該協議基於TCP,是一個協議族,包括RTMP基本協議及RTMPT/RTMPS/RTMPE等多種變種。RTMP是一種設計用來進行實時資料通訊的網路協議,主要用來在Flash/A
經典排序演算法分析及實現
一、排序概念 1. 排序:將一組雜亂無章的資料按照一定的規律組織起來,就稱為排序。 2. 資料表:待排序的資料元素的有限集合。 3. 排序碼:通常資料元素有多個屬性域,其中有一個屬性域可以用來區分元素,作為排序依據,該域即為排序碼。 * 若在資料表中各個元
資訊摘要演算法之二:SHA1演算法分析及實現
SHA演算法,即安全雜湊演算法(Secure Hash Algorithm)是一種與MD5同源的資料加密演算法,該演算法經過加密專家多年來的發展和改進已日益完善,現在已成為公認的最安全的雜湊演算法之一,並被廣泛使用。1、概述SHA演算法能計算出一個數位資訊所對應到的,長度固定
分散式系統選主場景分析及實現
一:需要選主的場景 1:服務有多臺機器,取其中一臺去執行任務。多臺機器同時執行會出問題,如將資料庫中狀態為失敗的記錄取出來重新執行,如果多臺機器同時執行,會導致一個失敗的任務被多臺機器同時執行。 2:服務有多臺機器,選其中一臺作為主,主負責任務的分發,大家一起消費並處理任務。還是將資料庫中狀態為失敗的記錄取
direct IO 核心實現分析及揭示一個坑——基於3.10.0-693.11.1
linux的讀寫系統呼叫提供了一個O_DIRECT標記,可以讓嘗試繞過快取,直接對磁碟進行讀寫(為啥是嘗試繞過?當直接落盤失敗時還要通過快取去落盤)。為了能實現直接落盤,使用direct IO限制多多,檔案偏移得對齊到磁碟block,記憶體地址得對齊到磁碟block,讀寫size也得對齊