(五) OBEX
介绍
一、什么是OBEX
,它有什么用途?
OBEX 全称为Object Exchange ,中文对象交换,所以称之为对象交换协议。它在此软件当中有着核心地位,文件传输和IrMC 同步都会使用到它。
OBEX 协议构建在IrDA 架构的上层.
OBEX 协议通过简单的使用“PUT ”和“GET ”命令实现在不同的设备、不同的平台之间方便、高效的交换信息。支持的设备广泛,例如PC ,PDA ,电话,摄像头,自动答录机,计算器,数据采集器,手表等等。
OBEX 协议定义了一种柔性的概念——objects 。也即是对象。这些对象可以包括文件,诊断信息,电子商务卡片,银行的存款等等。Objects 在这里没有高级的技术含义,而是视你的应用而定。
OBEX 协议小到可作“命令和控制”功能,例如对电视机,录像机等的操作。大道可以做很复杂的操作,例如数据库的事务处理和同步。
OBEX 能够具有以下几个特点:
1、 友好的应用——可实现快速开发。
2、 紧缩——可用在资源有限的小型设备上。
3、 跨平台
4、 柔性的数据支持。
5、 方便的作为其他Internet 传输协议的上层协议。
6、 可扩展性——提供了对未来需求的扩充支持而不影响以存在的实现。例如可扩展安全,数据压缩等。
7、 可测试可调试。
更为具体的关于OBEX 的介绍请查阅IrOBEX 协议。
二、OBEX 对象模型
关于Headers
对象模型回答了对象是如何在OBEX 协议描述的。这个模型必须包括被传输的对象和对对象的描述。为了做到这点,OBEX 定义了Headers 的概念。
一个Header 反映了对象的一个方面,例如名字、长度、描述文字或者对象本身。例如,一个文件对象demo.txt 会包含它的名字,一个类型标示为“text ”,长度和文件本身。
Headers 的构成
Headers 简单的由
和
。
HI 由一个字节组成,指出了Header 包含的内容以及它的格式。HV 包含了一个或者多个字节,其结构由HI 所决定。
所有的Header 都是可选的,取决于设备的类型和事务的种类。你可以使用所有的Header ,或者一些,或者没有。ID 可以使Header 可解析以及与传输顺序无关,也可以使不支持的Header 被忽略掉。
HI 又可以分为两部分,高2 位和低6 位。高2 位确定了HI 的编码方式(见表二),低6 位确定了HI 的意义(见表三)。两个表都是我从IrOBEX 中的表摘抄并部分翻译过来的。
表二
表三
关于常用Header 的更详尽的解释,更详尽信息请参考IrOBEX
1 、Name
Name 是一个用来描述对象名称的Header ,由以Null(0x00) 结尾的Unicode 字符串组成。例如:DEMO.TXT
2 、Length
Length 描述了对象的大小,由4 个字节组成。如果Length 事先知道,这个Header 应该被用到。这样可以让接受者迅速的知道需要分配多少空间,可使处理更为迅速。但这也不是必须的,有些情况下长度无法确认,但设备可以通过End-Body Header 知道什么时候结束。
3 、Time
Time 描述了对象的最后修改的时间。使用ISO8601 格式。
本地时间格式:YYYYMMDDTHHMMSS
UTC 时间格式:YYYYMMDDTHHMMSSZ
格式中的T 可以方便的区分日期和时间。UTC 时间使用Z 作为标记。建议使用UTC 时间。
4 、Body 、End-of-Body
Body Header 由HI 、一个2Byte 长度的描述和整个的对象本身。End-of-Body 组成和Body 组成一样,但标识了这是对象的最后一部分。如果对象本来就很小,就直接使用End-of-Body 。
三、请求(Request )和回应(Response )
OBEX 使用Request 和Response 作为最基本的操作。请求的每个Request 必然有一个Response ,否则可认为Request 失败。
Request 由一个或多个的Packet (包)组成,每个包的结构如下表
由于每个Request 可能有多个Packet ,opcode 的最高位称为Final bit 。如果被设置为1 ,那么说明这是Request 的最后一个Packet 。例如:当用PUT 操作发送一个大文件时,会有几个Packet 作为一个Request 。那么只有最后一个Packet 的FinalBit 设置为1 。
Response 也由一个或多个Packet 组成,每个包的结构如下表
同样的ResponseCode 的最高位也叫做FinalBit 。ResponseData 可能包含对象和Header ,或者其它信息。
下表列出了了常见的opcode 和responseCode ,更详尽的请参考IrOBEX 1.2 文档。
四、说明。
1、 Connect (连接)
此操作初始化会话然后设置参数。其Request 格式为
注:OBEX
版本现在为1.0
。
Response 格式为:
对于更多关于Connect
的说明请参考IrOBEX
2、 Disconnect (断开当前会话)
此操作断开OBEX 会话。例如断开当前FolderListing Service ,然后使用Connect 连接到IrMC Sync Service 实现同步通讯薄等功能。
Disconnect 格式为:
成功的断开会返回0Xa0
,拒绝会返回0xD3
3、 Put 操作
Put 操作从客户端发送一个对象到服务端。一般至少含有Name 和Length 两个Header 。对于文件而言有可能还有Date/Time Header 。
Put 操作的格式如下:
回应格式如下:
关于Put
操作的更详细的用法将在文件传输部分作解释。
4、 Get 操作
Get 操作从服务端返回一个对象。
Get 操作的格式如下:
回应格式如下:
关于Get
操作更详细的用法将在文件传输部分作解释。
5、 Abort 操作
Abort 操作中断一个多包操作(例如发送一个大文件)。Abort 操作可以包含描述中断原因的Description Header 。
Abort 操作的格式如下:
Abort
对应的应该是一个成功的操作(0xA0)
,指明这个操作已被接收并且服务端已经重新与客户端同步。如果返回的另外的值,客户端应该Disconnect
。
6、 SetPath
SetPath 操作用于切换对方的路径。通常使用一个Name Header 用于指定对方路径名称。如果为空,则返回默认目录,通常为根目录
SetPath 操作格式如下:
注:Flags
可以设置Bit0
和Bit1
。Bit0
表示退回到上一层目录;Bit1
表示如果目录不存在就创建一个目录,否则返回一个错误。
回应格式如下:
五、实际例子
注:数据使用SerialMonitor 获得。客户端为PC ,服务端为西门子M55 手机。
1、 Connect 、Disconnect
ÇConnect Request :
80 00 1A 10 00 40 06 46 00 13 6B 01 CB 31 41 06 €[email protected].Ë1A.
11 D4 9A 77 00 50 DA 3F 47 1F .Ôšw.PÚ?G.
ÈConnect Response :
A0 00 1F 10 00 01 DA CB 00 00 01 00 4A 00 13 6B .....ÚË....J..k
01 CB 31 41 06 11 D4 9A 77 00 50 DA 3F 47 1F .Ë1A..Ôšw.PÚ?G.
ÇDisconnect Request :
81 00 03 ..
ÈDisconnect Response :
A0 00 03 ..
该实例首先连接到手机,然后使用Disconnect 脱离连接。
ÇConnect Request :
80 :Connect
00 1A :包长度26 字节
10 :OBEX 版本1.0
00 :总是0
40 06 :最大包长度16390 字节。
46 :HI ,Target (目标)。0x40 开头,表示后面跟2 个字节的长度描述。
00 13 :Header 长度19
6B…. :对应的Target
ÈConnect Response :
A0 :OK ,Success
00 1F :包长度31 字节
10 :OBEX 版本1.0
00 :总是0
01 DA :最大包长度474 字节
CB :Connection ID=0x100 。0xC0 开头,表示后面跟4 个字节的值。
4A 00 13 :Who Header 。长度0x13 。
6B… :Who Header 值。
2、 Put ,Get ,SetPath
例一:如何下载手机\Sound 目录里面的21680.mid 文件。大小为313 字节。
整个过程分为:
连接 Æ 切换到根目录 Æ 切换到Sound 目录 ÆGet (21680.mid )
具体过程:
……(连接部分省略)
Ç 切换到根目录,Name Header(0x01) 内容为空
85 00 08 02 00 01 00 03 ….......
È 响应
A0 00 03 ..
Ç 切换到\Sound 目录。Name Header(0x01) 长度0x11 。
85 00 16 02 00 01 00 11 00 53 00 6F 00 75 00 6E …........S.o.u.n
00 64 00 73 00 00 .d.s..
È 响应
A0 00 03 ..
ÇGet 请求。Name Header(0x01) 指定文件名
83 00 1A 01 00 17 00 32 00 31 00 36 00 38 00 30 ƒ......2.1.6.8.0
00 2E 00 6D 00 69 00 64 00 00 ...m.i.d..
È 回应
0x90 说明需要继续。
0xC3 指明文件长度00 00 01 39 。
0x48 说明是文件的一部分。
90 01 44 C3 00 00 01 39 48 01 3C 4D ….
ÇGet 请求。由于服务端返回0x90 ,所以继续发送Get
83 00 03 ƒ..
È 回应。成功。服务端发送0x49 说明是对象最后一部分。
A0 00 06 49 00 03 ..I..
例二:说明如何获取大文件,主要介绍Get 部分。
取得\Pictures\102725.jpg ,大小5314 字节。
整个过程分为:
连接 Æ 切换到根目录 Æ 切换到Pictures 目录 ÆGet (102725.jpg ) ÆGet….
ÇGet 请求。Name Header 值为102725.jpg
83 00 1C 01 00 19 00 31 00 30 00 32 00 37 00 32 ƒ......1.0.2.7.2
00 35 00 2E 00 6A 00 70 00 67 00 00 .5...j.p.g..
È 返回一个Body 。客户端应该继续发送Get
90 01 D3 C3 00 00 14 C2 48 01 CB FF D8 FF E0 00 .ÓÃ...ÂH.ËÿØÿà.
10 4A 46 49 46 00 01 01 01 02 58 02 58 00 00 FF .JFIF.....X.X..ÿ
…..
ÇGet 请求。
83 00 03 ƒ..
È 返回第二个Body 。客户端继续发送Get
90 01 D7 48 01 D4 6A 60 99 1C A2 74 4C 92 67 BC .×H.Ôj`™.¢tL’g¼
A9 AA 84 CD 6B 20 83 83 F4 BB DF 8B BC 58 A4 DC ©ª„Ík ƒƒô»ß‹¼X¤Ü
……
……(省略若干重复过程)
ÇGet 请求。由于服务端返回0x90 ,所以继续发送Get
83 00 03 ƒ..
È 回应。成功。服务端发送0x49 说明是对象最后一部分。
A0 00 06 49 00 03 ..I..
例三:发送文件到\Sound\1.mid 。大小313 字节
整个过程分为:
连接 Æ 切换到根目录 Æ 切换到Sound 目录 ÆPut Æ…
具体过程:
……(省略连接切换部分)
ÇPut 操作
0x82 :Put 操作,FinalBit 设置
0x01 :NameHeader 。文件名1.mid
0xC3 :Length 。文件大小
0x44 :日期和时间。这里为2005 年2 月14 日 ,19 :49 :38 。使用本地时间。
0x49 :End-of-Body 。文件的最后部分。
82 01 65 01 00 0F 00 31 00 2E 00 6D 00 69 00 64 ‚.e....1...m.i.d
00 00 C3 00 00 01 39 44 00 12 32 30 30 35 30 32 ..Ã...9D..200502
31 34 54 31 39 34 39 33 38 49 01 3C 4D 54 68 64 14T194938I.
È
回应
A0 00 03 ..
例四:发送文件到\Pictures\102725.jpg ,大小5314 字节。
过程分为:
连接 Æ 切换到根目录 Æ 切换到\Pictures 目录 ÆPut Æ…
具体过程:
……(省略连接切换部分)
ÇPut 操作
0x02 :Put 操作,FianlBit 没有设置。说明还有剩余部分需要发送。
0x01 :NameHeader 。文件名102725.jpg
0xC3 :Length 。文件大小
0x44 :日期和时间。这里为2005 年2 月14 日 ,19 :57 :52 。使用本地时间。
0x48 :Body 。文件的一部分。
02 01 D0 01 00 19 00 31 00 30 00 32 00 37 00 32 ..Ð....1.0.2.7.2
00 35 00 2E 00 6A 00 70 00 67 00 00 C3 00 00 14 .5...j.p.g..Ã...
C2 44 00 12 32 30 30 35 30 32 31 34 54 31 39 35 ÂD..20050214T195
37 35 32 48 01 9D FF D8 FF E0 00 10 4A 46 49 46 752H.ÿØÿà..JFIF
……
È 回应。客户端继续发送
90 00 03
ÇPut 操作
0x02 :Put 操作,FianlBit 没有设置。说明还有剩余部分需要发送。
0x48 :Body 。文件的一部分。
注意:不在需要设置多余的Header 。
02 01 D4 48 01 D1 F3 C0 F1 2D 5A E9 98 B1 1B 71 ..ÔH.ÑóÀñ-Z阱.q
47 96 5B 45 30 BD 3C 7E 2B D7 AE 82 6B DF 2C 42 G–[E0½<~+×®‚kß,B
B5 BA 21 D3 6B 16 B5 B8 DB 4F D4 23 DB 11 C6 4C µº!Ók.µ¸ÛOÔ#Û.ÆL
……
……(省略若干重复过程)
ÇPut 操作
0x82 :Put 操作,FinalBit 设置。说明这是最后一部分
0x49 :End-of-Body 。文件的最后部分。
82 01 22 49 01 1F F6 75 BF 01 3C 02 49 48 E4 48 ‚."I..öu¿.<.IHäH
6F 3E FF 00 2D 51 25 CF 32 D8 39 5F 25 D8 88 44 o>ÿ.-Q%Ï2Ø9_%؈D
…..
È 回应。成功
A0 00 03
HI 由一个字节组成,指出了Header 包含的内容以及它的格式。HV 包含了一个或者多个字节,其结构由HI 所决定。
所有的Header 都是可选的,取决于设备的类型和事务的种类。你可以使用所有的Header ,或者一些,或者没有。ID 可以使Header 可解析以及与传输顺序无关,也可以使不支持的Header 被忽略掉。
HI 又可以分为两部分,高2 位和低6 位。高2 位确定了HI 的编码方式(见表二),低6 位确定了HI 的意义(见表三)。两个表都是我从IrOBEX 中的表摘抄并部分翻译过来的。
表二
HI的第8和第7位 |
意义 |
00(0x00) |
以Null(0x00)结尾的的Unicode文字。2个字节的无符号整数长度前缀。 |
01(0x40) |
Byte块,2个字节的无符号整数前缀。 |
10(0x80) |
1Byte容量。 |
11(0xC0) |
4Byte容量,以高位先传输为原则。 |
HI |
Header名称 |
描述 |
0xC0 |
Count |
连接中用于指名对象的数量。 |
0x01 |
Name |
对象的名字。一般为文件名。 |
0x42 |
Type |
对象的类型。例如text,html,binary,manufacture specific |
0x44 0xC4 |
Time |
时间戳。ISO 8601版本 时间戳。4Byte版本(用于兼容) |
0x05 |
Description |
对对象的文本描述 |
0x46 |
Target |
操作的目的服务名 |
0x47 |
HTTP |
一个HTTP1.x头 |
0x48 |
Body |
对象的一部分 |
0x49 |
End of body |
对象的最后一部分 |
0x4A |
Who |
OBEX Application标识,用于表明是否是同一个应用。 |
0xCB |
Connection ID |
用于OBEX多路连接的标识 |
0x4C |
App.Parameters |
扩展的应用层请求和回复信息 |
0x4D |
Auth.Challenge |
Authentication digest-challenge |
0x4E |
Auth.Response |
Authentication digest-response |
0x4F |
Object Class |
对象的OBEX对象类 |
0x10 to 0x2F |
Reserved |
保留 |
0x30 to 0x3F |
User defined |
用户自定义的。 |
关于常用Header 的更详尽的解释,更详尽信息请参考IrOBEX
1 、Name
Name 是一个用来描述对象名称的Header ,由以Null(0x00) 结尾的Unicode 字符串组成。例如:DEMO.TXT
2 、Length
Length 描述了对象的大小,由4 个字节组成。如果Length 事先知道,这个Header 应该被用到。这样可以让接受者迅速的知道需要分配多少空间,可使处理更为迅速。但这也不是必须的,有些情况下长度无法确认,但设备可以通过End-Body Header 知道什么时候结束。
3 、Time
Time 描述了对象的最后修改的时间。使用ISO8601 格式。
本地时间格式:YYYYMMDDTHHMMSS
UTC 时间格式:YYYYMMDDTHHMMSSZ
格式中的T 可以方便的区分日期和时间。UTC 时间使用Z 作为标记。建议使用UTC 时间。
4 、Body 、End-of-Body
Body Header 由HI 、一个2Byte 长度的描述和整个的对象本身。End-of-Body 组成和Body 组成一样,但标识了这是对象的最后一部分。如果对象本来就很小,就直接使用End-of-Body 。
三、请求(Request )和回应(Response )
OBEX 使用Request 和Response 作为最基本的操作。请求的每个Request 必然有一个Response ,否则可认为Request 失败。
Request 由一个或多个的Packet (包)组成,每个包的结构如下表
Request
数据包结构
Byte 0 |
Byte 1,2 |
Byte 3 to n |
操作码(opcode)
|
Packet Length
(包长度)
|
Headers
或请求信息
|
由于每个Request 可能有多个Packet ,opcode 的最高位称为Final bit 。如果被设置为1 ,那么说明这是Request 的最后一个Packet 。例如:当用PUT 操作发送一个大文件时,会有几个Packet 作为一个Request 。那么只有最后一个Packet 的FinalBit 设置为1 。
Response 也由一个或多个Packet 组成,每个包的结构如下表
Response
数据包结构
Byte 0 |
Byte 1,2 |
Byte 3 to n |
Response Code
(返回值)
|
Response Length
(回应长度)
|
ResponseData
回应的数据
|
同样的ResponseCode 的最高位也叫做FinalBit 。ResponseData 可能包含对象和Header ,或者其它信息。
下表列出了了常见的opcode 和responseCode ,更详尽的请参考IrOBEX 1.2 文档。
opcode
Opcode(w/high bit set) |
定义 |
意义 |
0x80 *
|
Connect
|
连接
|
0x81 *
|
Disconnect
|
断开连接
|
0x02(0x82)
|
Put
|
发送一个对象
|
0x03(0x83)
|
Get
|
取得一个对象
|
0x04(0x84)
|
Reserved
|
保留的
|
0x85 *
|
SetPath
|
设置路径
|
0xFF *
|
Abort
|
取消当前的操作
|
0x06
到0x0F
|
Reserved
|
作为扩展保留
|
0x10
到0x1F
|
User definable
|
用户自定义的
|
*
总是设置FinalBit
ResponseCode
ResponseCode |
定义 |
0x10(0x90)
|
Continue
(继续)
|
0x20
(0xA0
)
|
OK
,Success
|
0x40(0xC0)
|
Bad Request
(服务端不明白Request
)
|
0x41(0xC1)
|
Unauthorized
(未授权的)
|
0x43(0xC3)
|
Fobidden
(禁止——服务器明白Request
,但拒绝)
|
0x44(0xC4)
|
Not Found
(未找到)
|
1、 Connect (连接)
此操作初始化会话然后设置参数。其Request 格式为
Byte 0 |
Byte 1,2 |
Byte 3 |
Byte 4 |
Byte 5,6 |
Byte 7 to n |
0x80
|
包长度
|
OBEX
版本
|
标志
|
最大OBEX
包长度
|
可选Header
|
Response 格式为:
Byte 0 |
Byte 1,2 |
Byte 3 |
Byte 4 |
Byte 5,6 |
Byte 7 to n |
ResponseCode
|
包长度
|
OBEX
版本
|
标志
|
最大OBEX
包长度
|
可选Header |
2、 Disconnect (断开当前会话)
此操作断开OBEX 会话。例如断开当前FolderListing Service ,然后使用Connect 连接到IrMC Sync Service 实现同步通讯薄等功能。
Disconnect 格式为:
Byte 0 |
Bytes 1,2 |
Bytes 3 to n |
0x81
|
包长度
|
可选Header
|
3、 Put 操作
Put 操作从客户端发送一个对象到服务端。一般至少含有Name 和Length 两个Header 。对于文件而言有可能还有Date/Time Header 。
Put 操作的格式如下:
Byte 0 |
Bytes 1,2 |
Bytes 3 to n |
0x02(
当FinalBit
设置时为0x82)
|
PacketLength
包长度
|
一组Header
|
Byte 0 |
Bytes 1,2 |
Bytes 3 to n |
ResponseCode
(要求继续为0x90
;成功为0xA0
)
|
包长度
|
可选Header
|
4、 Get 操作
Get 操作从服务端返回一个对象。
Get 操作的格式如下:
Byte 0 |
Bytes 1,2 |
Bytes 3 to n |
0x03
|
包长度
|
一组Header
|
Byte 0 |
Bytes 1,2 |
Bytes 3 to n |
Response Code
|
包长度
|
可选Header
|
5、 Abort 操作
Abort 操作中断一个多包操作(例如发送一个大文件)。Abort 操作可以包含描述中断原因的Description Header 。
Abort 操作的格式如下:
Byte 0 |
Bytes 1,2 |
Bytes 3 to n |
0xFF
|
包长度
|
可选Header
|
6、 SetPath
SetPath 操作用于切换对方的路径。通常使用一个Name Header 用于指定对方路径名称。如果为空,则返回默认目录,通常为根目录
SetPath 操作格式如下:
Byte 0 |
Bytes 1,2 |
Byte 3 |
Byte 4 |
Bytes 5 to n |
0x85
|
包长度
|
Flags
|
Constants
(常数)
|
可选Header
|
回应格式如下:
Byte 0 |
Bytes 1,2 |
Bytes 3 to n |
ResponseCode
|
包长度
|
可选Response Header
|
五、实际例子
注:数据使用SerialMonitor 获得。客户端为PC ,服务端为西门子M55 手机。
1、 Connect 、Disconnect
ÇConnect Request :
80 00 1A 10 00 40 06 46 00 13 6B 01 CB 31 41 06 €[email protected].Ë1A.
11 D4 9A 77 00 50 DA 3F 47 1F .Ôšw.PÚ?G.
ÈConnect Response :
A0 00 1F 10 00 01 DA CB 00 00 01 00 4A 00 13 6B .....ÚË....J..k
01 CB 31 41 06 11 D4 9A 77 00 50 DA 3F 47 1F .Ë1A..Ôšw.PÚ?G.
ÇDisconnect Request :
81 00 03 ..
ÈDisconnect Response :
A0 00 03 ..
该实例首先连接到手机,然后使用Disconnect 脱离连接。
ÇConnect Request :
80 :Connect
00 1A :包长度26 字节
10 :OBEX 版本1.0
00 :总是0
40 06 :最大包长度16390 字节。
46 :HI ,Target (目标)。0x40 开头,表示后面跟2 个字节的长度描述。
00 13 :Header 长度19
6B…. :对应的Target
ÈConnect Response :
A0 :OK ,Success
00 1F :包长度31 字节
10 :OBEX 版本1.0
00 :总是0
01 DA :最大包长度474 字节
CB :Connection ID=0x100 。0xC0 开头,表示后面跟4 个字节的值。
4A 00 13 :Who Header 。长度0x13 。
6B… :Who Header 值。
2、 Put ,Get ,SetPath
例一:如何下载手机\Sound 目录里面的21680.mid 文件。大小为313 字节。
整个过程分为:
连接 Æ 切换到根目录 Æ 切换到Sound 目录 ÆGet (21680.mid )
具体过程:
……(连接部分省略)
Ç 切换到根目录,Name Header(0x01) 内容为空
85 00 08 02 00 01 00 03 ….......
È 响应
A0 00 03 ..
Ç 切换到\Sound 目录。Name Header(0x01) 长度0x11 。
85 00 16 02 00 01 00 11 00 53 00 6F 00 75 00 6E …........S.o.u.n
00 64 00 73 00 00 .d.s..
È 响应
A0 00 03 ..
ÇGet 请求。Name Header(0x01) 指定文件名
83 00 1A 01 00 17 00 32 00 31 00 36 00 38 00 30 ƒ......2.1.6.8.0
00 2E 00 6D 00 69 00 64 00 00 ...m.i.d..
È 回应
0x90 说明需要继续。
0xC3 指明文件长度00 00 01 39 。
0x48 说明是文件的一部分。
90 01 44 C3 00 00 01 39 48 01 3C 4D ….
ÇGet 请求。由于服务端返回0x90 ,所以继续发送Get
83 00 03 ƒ..
È 回应。成功。服务端发送0x49 说明是对象最后一部分。
A0 00 06 49 00 03 ..I..
例二:说明如何获取大文件,主要介绍Get 部分。
取得\Pictures\102725.jpg ,大小5314 字节。
整个过程分为:
连接 Æ 切换到根目录 Æ 切换到Pictures 目录 ÆGet (102725.jpg ) ÆGet….
ÇGet 请求。Name Header 值为102725.jpg
83 00 1C 01 00 19 00 31 00 30 00 32 00 37 00 32 ƒ......1.0.2.7.2
00 35 00 2E 00 6A 00 70 00 67 00 00 .5...j.p.g..
È 返回一个Body 。客户端应该继续发送Get
90 01 D3 C3 00 00 14 C2 48 01 CB FF D8 FF E0 00 .ÓÃ...ÂH.ËÿØÿà.
10 4A 46 49 46 00 01 01 01 02 58 02 58 00 00 FF .JFIF.....X.X..ÿ
…..
ÇGet 请求。
83 00 03 ƒ..
È 返回第二个Body 。客户端继续发送Get
90 01 D7 48 01 D4 6A 60 99 1C A2 74 4C 92 67 BC .×H.Ôj`™.¢tL’g¼
A9 AA 84 CD 6B 20 83 83 F4 BB DF 8B BC 58 A4 DC ©ª„Ík ƒƒô»ß‹¼X¤Ü
……
……(省略若干重复过程)
ÇGet 请求。由于服务端返回0x90 ,所以继续发送Get
83 00 03 ƒ..
È 回应。成功。服务端发送0x49 说明是对象最后一部分。
A0 00 06 49 00 03 ..I..
例三:发送文件到\Sound\1.mid 。大小313 字节
整个过程分为:
连接 Æ 切换到根目录 Æ 切换到Sound 目录 ÆPut Æ…
具体过程:
……(省略连接切换部分)
ÇPut 操作
0x82 :Put 操作,FinalBit 设置
0x01 :NameHeader 。文件名1.mid
0xC3 :Length 。文件大小
0x44 :日期和时间。这里为2005 年2 月14 日 ,19 :49 :38 。使用本地时间。
0x49 :End-of-Body 。文件的最后部分。
82 01 65 01 00 0F 00 31 00 2E 00 6D 00 69 00 64 ‚.e....1...m.i.d
00 00 C3 00 00 01 39 44 00 12 32 30 30 35 30 32 ..Ã...9D..200502
31 34 54 31 39 34 39 33 38 49 01 3C 4D 54 68 64 14T194938I.
A0 00 03 ..
例四:发送文件到\Pictures\102725.jpg ,大小5314 字节。
过程分为:
连接 Æ 切换到根目录 Æ 切换到\Pictures 目录 ÆPut Æ…
具体过程:
……(省略连接切换部分)
ÇPut 操作
0x02 :Put 操作,FianlBit 没有设置。说明还有剩余部分需要发送。
0x01 :NameHeader 。文件名102725.jpg
0xC3 :Length 。文件大小
0x44 :日期和时间。这里为2005 年2 月14 日 ,19 :57 :52 。使用本地时间。
0x48 :Body 。文件的一部分。
02 01 D0 01 00 19 00 31 00 30 00 32 00 37 00 32 ..Ð....1.0.2.7.2
00 35 00 2E 00 6A 00 70 00 67 00 00 C3 00 00 14 .5...j.p.g..Ã...
C2 44 00 12 32 30 30 35 30 32 31 34 54 31 39 35 ÂD..20050214T195
37 35 32 48 01 9D FF D8 FF E0 00 10 4A 46 49 46 752H.ÿØÿà..JFIF
……
È 回应。客户端继续发送
90 00 03
ÇPut 操作
0x02 :Put 操作,FianlBit 没有设置。说明还有剩余部分需要发送。
0x48 :Body 。文件的一部分。
注意:不在需要设置多余的Header 。
02 01 D4 48 01 D1 F3 C0 F1 2D 5A E9 98 B1 1B 71 ..ÔH.ÑóÀñ-Z阱.q
47 96 5B 45 30 BD 3C 7E 2B D7 AE 82 6B DF 2C 42 G–[E0½<~+×®‚kß,B
B5 BA 21 D3 6B 16 B5 B8 DB 4F D4 23 DB 11 C6 4C µº!Ók.µ¸ÛOÔ#Û.ÆL
……
……(省略若干重复过程)
ÇPut 操作
0x82 :Put 操作,FinalBit 设置。说明这是最后一部分
0x49 :End-of-Body 。文件的最后部分。
82 01 22 49 01 1F F6 75 BF 01 3C 02 49 48 E4 48 ‚."I..öu¿.<.IHäH
6F 3E FF 00 2D 51 25 CF 32 D8 39 5F 25 D8 88 44 o>ÿ.-Q%Ï2Ø9_%؈D
…..
È 回应。成功
A0 00 03