咨詢電話:023-6276-4481
熱門文章
電 話:023-6276-4481
郵箱:broiling@qq.com
地址:重慶市南岸區(qū)亞太商谷6幢25-2
十一月開始沒有做什么項(xiàng)目,每天站在在辦公室窗前靜靜地看著樓下的行人來(lái)來(lái)往往,然后等待著領(lǐng)工資的時(shí)刻。為了讓智慧的大腦不因無(wú)所事是而僵硬,我決定找點(diǎn)傷腦筋的事情來(lái)維持腦袋的正常運(yùn)轉(zhuǎn)。經(jīng)過(guò)考慮,決定用VB.net實(shí)現(xiàn)紅外線文件傳輸?shù)睦獭?/span>
一、OBEX協(xié)議淺析
目前的紅外線傳輸大都遵循OBEX協(xié)議,這是由微軟、蘋果、諾基亞等公司專門為紅外線傳輸而制定的一整套協(xié)議規(guī)則。最新協(xié)議版本是1.3版,在官方網(wǎng)站上下載要20美元(有錢的可以去下,我反正是玩玩,叫我交錢是不可能的,本文中實(shí)現(xiàn)的依據(jù)是在網(wǎng)上找到的OBEX協(xié)議1.2版本的文檔)。協(xié)議文檔的第二章OBEX Object Model是關(guān)鍵部份,實(shí)現(xiàn)文件傳輸必須對(duì)這章說(shuō)明仔細(xì)研究清楚。以下先就對(duì)這章的一些關(guān)鍵點(diǎn)進(jìn)行講解。
1、OBEX協(xié)議的對(duì)象模型
1)OBEX協(xié)議使用一系列的數(shù)據(jù)包(header)來(lái)進(jìn)行某種對(duì)象(通常是文件)的傳輸,其基本格式是這樣的:
<Header ID>'數(shù)據(jù)包的標(biāo)識(shí)
<Header Value> '數(shù)據(jù)包內(nèi)的數(shù)據(jù)
其中<Header ID>是個(gè)單字節(jié)(八位二進(jìn)制)字符,這個(gè)字符的低六位標(biāo)識(shí)數(shù)據(jù)包代表的意義,高兩位表示這個(gè)數(shù)據(jù)包的總長(zhǎng)度的表達(dá)方式,如下表:
高倆位二進(jìn)制數(shù)據(jù) | 意義 |
00 | 這個(gè)數(shù)據(jù)包的<header Value>是一個(gè)以空字符結(jié)尾的unicode字符串 |
01 | 這個(gè)數(shù)據(jù)包的<header Value>是一個(gè)以空字符結(jié)尾的單字節(jié)組成的字符串,<header Value>的前兩個(gè)字節(jié)數(shù)據(jù)組成的16位整數(shù)表示整個(gè)數(shù)據(jù)包的長(zhǎng)度(包括<header id>及<header value>的總長(zhǎng)) |
10 | <header Value>的長(zhǎng)度只有一個(gè)字節(jié)數(shù)據(jù) |
11 | <header Value>的長(zhǎng)度只有四個(gè)字節(jié)數(shù)據(jù),并以網(wǎng)格數(shù)據(jù)格式排列(高位數(shù)據(jù)放在低位字節(jié)中存儲(chǔ)) |
注意:在<header Value>的16位數(shù)據(jù)(如包的長(zhǎng)度、Unicode字符在發(fā)送方均要做高位字放在低位字發(fā)送的處理。由于沒注意這個(gè)問題,我曾在開頭的四五天時(shí)間里嘔血數(shù)升而一直沒有成功將數(shù)據(jù)發(fā)送成功)
在應(yīng)用中,數(shù)據(jù)包可以嵌套。也就是:Header Value可以包含其它的數(shù)據(jù)包,所以長(zhǎng)度標(biāo)識(shí)非常重要,它可以幫助軟件的實(shí)現(xiàn)根據(jù)包的長(zhǎng)度迅速分離出包內(nèi)的數(shù)據(jù)。
在本文實(shí)現(xiàn)中主要用到的數(shù)據(jù)包標(biāo)識(shí)如下(其余的項(xiàng)請(qǐng)參閱詳細(xì)官方協(xié)議):
常用數(shù)據(jù)包標(biāo)識(shí)列表
十六進(jìn)制值 | 標(biāo)識(shí)名稱 | 標(biāo)識(shí)含義 |
0x01 | Name | 標(biāo)記對(duì)象的名稱(通常是文件的文件名) |
0xC3 | Length | 以字節(jié)為單位計(jì)算的對(duì)象長(zhǎng)度 |
0x44 | Time | 時(shí)間(以ISO 8601規(guī)范為標(biāo)準(zhǔn)) |
0x480x49 | BodyEnd of Body | 標(biāo)識(shí)一個(gè)對(duì)象數(shù)據(jù)塊的開始標(biāo)識(shí)這是對(duì)象的最后一個(gè)數(shù)據(jù)塊 |
OBEX協(xié)議數(shù)據(jù)對(duì)象傳輸是按照服務(wù)器端/客戶端的方式進(jìn)行的,每個(gè)操作均提供一個(gè)操作碼以明確操作的含義。以下給出部分?jǐn)?shù)據(jù)發(fā)送所需操作碼列表:
0x80 | Connect | 標(biāo)識(shí)申請(qǐng)開始一個(gè)對(duì)象傳輸會(huì)話,并可以在這個(gè)數(shù)據(jù)包中告知紅外接收方一些必要的兼容性信息。 |
0x81 | Disconnect | 標(biāo)識(shí)對(duì)象傳輸會(huì)話結(jié)束 |
0x020x82 | PutFinal_Put | 發(fā)送對(duì)象的put動(dòng)作(當(dāng)標(biāo)識(shí)為0x82時(shí)說(shuō)明這是最后的一個(gè)Put動(dòng)作) |
0xA0 | Success | 說(shuō)明接收端已成功收到put動(dòng)作發(fā)送的所有數(shù)據(jù)(一般是在成功收到Final_Put標(biāo)識(shí)的數(shù)據(jù)包后的反饋) |
0x90 | Continue | 說(shuō)明接收端已收到put動(dòng)作發(fā)送的數(shù)據(jù),因?yàn)镕inal_Put還沒出現(xiàn),所以要求發(fā)送端繼續(xù)發(fā)送數(shù)據(jù)。 |
發(fā)送方和接收方是的通信的基本格式如下:
字節(jié)0 | 字節(jié)1,2 | 字節(jié)三以后的數(shù)據(jù) |
操作碼 | 整個(gè)通信數(shù)據(jù)包的長(zhǎng)度 | 通訊的數(shù)據(jù) |
以下結(jié)合基本傳輸步驟,對(duì)上文列出的數(shù)據(jù)包使用方法進(jìn)行講解:
1、由發(fā)送方向接收文件的接收方進(jìn)行連接請(qǐng)求。
發(fā)送方需要使用的操作碼為Connect,在OBEX協(xié)議中對(duì)Connect數(shù)據(jù)包格式作如下規(guī)定:
字節(jié)0 | 字節(jié)1、2 | 字節(jié)3 | 字節(jié)4 | 字節(jié)5、6 | 字節(jié)7 |
Connect操作碼(0x80) | Connect數(shù)據(jù)包的總長(zhǎng)度 | OBEX協(xié)議的版本(目前為1.0,16進(jìn)制表示為0x10) | 保留未用,設(shè)為0 | 最大可處理的OBEX包長(zhǎng)度 | 其它的數(shù)據(jù)包(可選) |
服務(wù)端根據(jù)連接的請(qǐng)求向客戶端做出響應(yīng):
字節(jié)0 | 字節(jié)1、2 | 字節(jié)3 | 字節(jié)4 | 字節(jié)5、6 | 字節(jié)7 |
響應(yīng)的操作碼 | 響應(yīng)數(shù)據(jù)包的總長(zhǎng)度 | OBEX協(xié)議的版本(目前為1.0,16進(jìn)制表示為0x10) | 保留未用,設(shè)為0 | 最大可處理的OBEX包長(zhǎng)度 | 其它的數(shù)據(jù)包(可選) |
如果接收方允許連接,響應(yīng)的操作碼會(huì)為Success(0xA0)其它的響應(yīng)操作碼均被認(rèn)為連接失敗。
2、發(fā)送方向接收方發(fā)送數(shù)據(jù)
發(fā)送方通過(guò)put和Final_Put這兩個(gè)操作將傳輸?shù)臄?shù)據(jù)信息向接收方發(fā)送。
發(fā)送方的Put/Final_Put使用格式。
字節(jié)0 | 字節(jié)1,2 | 字節(jié)三以后的數(shù)據(jù) |
Put操作碼(0x02)Final_Put操作碼(0x82) | 整個(gè)通信數(shù)據(jù)包的長(zhǎng)度 | 通訊的數(shù)據(jù)(由其它的例如name/body等數(shù)據(jù)包構(gòu)成) |
當(dāng)最后一次傳輸對(duì)象的數(shù)據(jù)時(shí)要使用Final_Put告知接收方這是最后一個(gè)數(shù)據(jù)包了,以便接收方根據(jù)接收到的數(shù)據(jù)進(jìn)行處理(例如將接收到的文件存盤)。
接收方的響應(yīng)格式:
字節(jié)0 | 字節(jié)1,2 | 字節(jié)三以后的數(shù)據(jù) |
響應(yīng)操作碼典型的有兩個(gè)值:Success操作碼(0xA0)Continue操作碼(0x90 ) | 整個(gè)通信數(shù)據(jù)包的長(zhǎng)度 | 通訊的數(shù)據(jù)(由其它的例如name/body等數(shù)據(jù)包構(gòu)成) |
如果接收方成功收到put操作的數(shù)據(jù),應(yīng)該返回Continue開始的響應(yīng)信息,告知發(fā)送方繼續(xù)發(fā)送,在成功收到Final_Put發(fā)送的數(shù)據(jù)后,應(yīng)返回Success響應(yīng)信息,告知發(fā)送方整個(gè)對(duì)象都接收完成。(但由于部分適配器只會(huì)返回Success響應(yīng),出于兼容性考慮,在編程中應(yīng)理解為無(wú)論接收到Success或Continue響應(yīng)都代表數(shù)據(jù)發(fā)送成功。)
3、發(fā)送方關(guān)閉連接
發(fā)送方在最后應(yīng)以Disconnect信息明確結(jié)束連接,這并不是必須的,但推薦使用。
發(fā)送方格式:
字節(jié)0 | 字節(jié)1,2 | 字節(jié)三以后的數(shù)據(jù) |
Disconnect操作碼 | 整個(gè)通信數(shù)據(jù)包的長(zhǎng)度 | 可選的通訊的數(shù)據(jù)(由其它的數(shù)據(jù)包構(gòu)成) |
接收方響應(yīng):
字節(jié)0 | 字節(jié)1,2 | 字節(jié)三以后的數(shù)據(jù) |
Success操作碼(0xA0)服務(wù)不可用操作碼(0xD3) | 整個(gè)通信數(shù)據(jù)包的長(zhǎng)度 | 可選的通訊的數(shù)據(jù)(由其它的數(shù)據(jù)包構(gòu)成) |
當(dāng)成功斷開時(shí),接收方會(huì)發(fā)送Success信息。否則,如果發(fā)送方的disconnect操作包含錯(cuò)誤信息(例如一個(gè)錯(cuò)誤的連接ID)時(shí),會(huì)返加0xD3操作碼。但并不能操作所有接收方的程序都實(shí)現(xiàn)這個(gè)響應(yīng)的功能,也就是說(shuō),發(fā)送方并不能保證一定會(huì)得到響應(yīng)信息。