2.1 WDP Layer
WDP在设计时就以UDP作为参考;实际编程中,如果底层已经实现IP层连接,比如GPRS/CSD类的连接,则直接使用UDP的接口编程即可。其它类型的连接(SMS/USSD等),需要实现这些底层转换。
参考文档:WAP-WDP-reference
2.2 WTP Layer
WTP层实际上是一种轻量级的事务处理层,通过TransactionID的机制和“请求-响应”机制确保消息传递的一致性和可靠性。
2.2.1 CLASS
WTP层有三种类别,分别为Class0/Class1/Class2,分别表示不同的可靠性机制,我们只讨论Class2类别。
客户端和服务器端之间使用的Class不能协商,只能由发起者指定。
2.2.2 TID
每一次浏览操作的事务都是由TID来保证的。在WTP层数据包中,大部分都包含TID字段。TID由两个字节组成,第0位是标记位,用于标记方向:发起者标记为0,响应者标记为1
Initiator: 0x00, 0x01
0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 |
Responder:
1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 |
WTP PDU类型
WTP层有以下几种消息:
▲
▲
▲
▲
▲
每种消息都是由一个或多个PDU组成。一个PDU是一个最小的协议数据单元。WTP层所有的PDU类型如下:
名称 | 值 |
(禁止使用) | 0x00 |
Invoke | 0x01 |
Result | 0x02 |
Ack | 0x03 |
Abort | 0x04 |
Segmented Invoke | 0x05 |
Segmented Result | 0x06 |
Negative Ack | 0x07 |
2.2.4 WTP PDU数据结构
▲
Bit/Octet | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
1 | CON | PDU Type=Invoke | GTR | TTR | RID | |||
2 | TID(Transaction ID) | |||||||
3 | ||||||||
4 | Version | TIDNew | U/P | RES | RES | TCL |
▲
Bit/Octet | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
1 | CON | PDU Type=Result | GTR | TTR | RID | |||
2 | TID(Transaction ID) | |||||||
3 |
▲
Bit/Octet | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
1 | CON | PDU Type=Ack | Tve/Tok | RES | RID | |||
2 | TID(Transaction ID) | |||||||
3 |
▲
Bit/Octet | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
1 | CON | PDU Type=Invoke | Abort Type | |||||
2 | TID(Transaction ID) | |||||||
3 | ||||||||
4 | Abort reason |
其它PDU不做介绍,上述一些位的具体含义,请参考相关规范。蓝色粗体部分都是比较主要的内容。
2.2.5 WTP基本交互流程
以下描述的基本流程主要应用于WTP Class2类别。
任何一个事务操作,都以Invoke消息作为初始消息;如果响应者接收到Invoke消息,并且发现该TID无法在缓存中匹配,则需要开始“三步握手”流程,即红色标记部分:发送Ack消息,询问发起者改Tid是否有效;发起者则回应一个Ack消息,说明该Tid是否有效。如果返回说明Tid无效,则响应者必须Abort此次事务(本图未标记这个Abort流程);如果Tid有效,则以后的事务操作均需携带这个Tid,直到这个事务结束。
WAP协议栈深入分析
3.1 关于WDP
WDP相当于UDP。这一层需要考虑的问题是UDP缺乏流量控制机制。在互联网上,一般网卡的MTU上限都是1500左右。所以当单个WDP数据包大于1500时,可能会被部分防火墙拒绝,或者被丢弃过长部分。因此必须在WTP层进行WDP数据包分解和重组(Segmented And Assemble),下节会详细描述。
在WAP协议规范中,一般WAP网关在UDP层默认接收的最大数据包长度为1400,超过这个长度一般被拒绝,除非在WSP层进行Capabilities协商。
3.2 WTP层深入分析
在前面的文章中描述了WTP层的基本交互流程和协议字段。这种流程是最基本、最简单的流程,仅适用于数据包<1400的情况。当传送的数据包有可能突破这个上限时(包括发起者和响应者),就必须采用分节和重组的机制。
WTP PDU结构中,头字段包括以下两位:
GTR | TTR | Desc |
0 | 0 | 不是最后一节 |
0 | 1 | 消息包的最后一节 |
1 | 0 | 分组包的最后一节 |
1 | 1 | 不支持分节重组 |
前面描述的基本流程就是GTR=1, TTR=1的情况,即不支持分节重组机制。如果支持分节重组机制,必须采用前三种状态(00,01,10)。在分节重组机制下,除了前面已介绍的WTP PDU,还需要了解以下三种专为分节重组机制使用的PDU:
▲
Bit/Octet | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
1 | CON | Type=Segmented Invoke | GTR | TTR | RID | |||
2 | TID(Transaction ID) | |||||||
3 | ||||||||
4 | Packet Sequence Number (PSN) |
▲
Bit/Octet | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
1 | CON | Type=Segmented Result | GTR | TTR | RID | |||
2 | TID(Transaction ID) | |||||||
3 | ||||||||
4 | Packet Sequence Number (PSN) |
▲
Bit/Octet | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
1 | CON | Type=Negative Ack | Reserved | RID | ||||
2 | TID(Transaction ID) | |||||||
3 | ||||||||
4 | Number of Missing Packets = N | |||||||
5 | Packet Sequence Number(s) of Missing Packets | |||||||
… | ||||||||
4+N |
采用分节重组机制的交互流程详细描述如下:
◆
◆
◆
◆
◆
图示流程如下: