跳到主要内容

Appendix A. 示例

Appendix A. 示例 (Examples)

本节给出若干 GET 请求消息流的简短示例. 这些示例展示了基本操作、存在重传时的操作以及组播场景.

图 16 展示了一个基本 GET 请求产生搭载式响应 (piggybacked response) 的过程: 客户端向服务器发送一个针对资源 coap://server/temperature 的可确认 (Confirmable) GET 请求, 消息 ID 为 0x7d34. 该请求包含一个 Uri-Path 选项 (Delta 0 + 11 = 11, Length 11, Value "temperature"); Token 留空. 该请求总长度为 16 字节. 服务器在确认该可确认请求的 Acknowledgement 消息中返回 2.05 (Content) 响应, 同时回显消息 ID 0x7d34 和空 Token 值. 该响应包含负载 "22.3 C", 长度为 11 字节.

Client  Server
| |
| |
+----->| Header: GET (T=CON, Code=0.01, MID=0x7d34)
| GET | Uri-Path: "temperature"
| |
| |
|<-----+ Header: 2.05 Content (T=ACK, Code=2.05, MID=0x7d34)
| 2.05 | Payload: "22.3 C"
| |
 0                   1                   2                   3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 1 | 0 | 0 | GET=1 | MID=0x7d34 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 11 | 11 | "temperature" (11 B) ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 1 | 2 | 0 | 2.05=69 | MID=0x7d34 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|1 1 1 1 1 1 1 1| "22.3 C" (6 B) ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

图 16: 可确认请求; 搭载式响应

图 17 展示了一个类似示例, 但请求和响应中包含非空 Token (值为 0x20), 因此大小分别增加到 17 字节和 12 字节.

Client  Server
| |
| |
+----->| Header: GET (T=CON, Code=0.01, MID=0x7d35)
| GET | Token: 0x20
| | Uri-Path: "temperature"
| |
| |
|<-----+ Header: 2.05 Content (T=ACK, Code=2.05, MID=0x7d35)
| 2.05 | Token: 0x20
| | Payload: "22.3 C"
| |
 0                   1                   2                   3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 1 | 0 | 1 | GET=1 | MID=0x7d35 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 0x20 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 11 | 11 | "temperature" (11 B) ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+


0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 1 | 2 | 1 | 2.05=69 | MID=0x7d35 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 0x20 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|1 1 1 1 1 1 1 1| "22.3 C" (6 B) ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

图 17: 可确认请求; 搭载式响应

在图 18 中, 可确认 GET 请求丢失. 经过 ACK_TIMEOUT 秒后, 客户端重传该请求, 从而得到与前一示例相同的搭载式响应.

Client  Server
| |
| |
+----X | Header: GET (T=CON, Code=0.01, MID=0x7d36)
| GET | Token: 0x31
| | Uri-Path: "temperature"
TIMEOUT |
| |
+----->| Header: GET (T=CON, Code=0.01, MID=0x7d36)
| GET | Token: 0x31
| | Uri-Path: "temperature"
| |
| |
|<-----+ Header: 2.05 Content (T=ACK, Code=2.05, MID=0x7d36)
| 2.05 | Token: 0x31
| | Payload: "22.3 C"
| |

图 18: 可确认请求 (已重传); 搭载式响应

在图 19 中, 服务器发送给客户端的第一个 Acknowledgement 消息丢失. 经过 ACK_TIMEOUT 秒后, 客户端重传该请求.

Client  Server
| |
| |
+----->| Header: GET (T=CON, Code=0.01, MID=0x7d37)
| GET | Token: 0x42
| | Uri-Path: "temperature"
| |
| |
| X----+ Header: 2.05 Content (T=ACK, Code=2.05, MID=0x7d37)
| 2.05 | Token: 0x42
| | Payload: "22.3 C"
TIMEOUT |
| |
+----->| Header: GET (T=CON, Code=0.01, MID=0x7d37)
| GET | Token: 0x42
| | Uri-Path: "temperature"
| |
| |
|<-----+ Header: 2.05 Content (T=ACK, Code=2.05, MID=0x7d37)
| 2.05 | Token: 0x42
| | Payload: "22.3 C"
| |

图 19: 可确认请求; 搭载式响应 (已重传)

在图 20 中, 服务器确认该可确认请求, 并在单独的可确认消息中发送 2.05 (Content) 响应. 注意, Acknowledgement 消息和可确认响应不一定按发送顺序到达. 客户端会确认该可确认响应.

Client  Server
| |
| |
+----->| Header: GET (T=CON, Code=0.01, MID=0x7d38)
| GET | Token: 0x53
| | Uri-Path: "temperature"
| |
| |
|<- - -+ Header: (T=ACK, Code=0.00, MID=0x7d38)
| |
| |
|<-----+ Header: 2.05 Content (T=CON, Code=2.05, MID=0xad7b)
| 2.05 | Token: 0x53
| | Payload: "22.3 C"
| |
| |
+- - ->| Header: (T=ACK, Code=0.00, MID=0xad7b)
| |

图 20: 可确认请求; 分离响应

图 21 展示了客户端在发送可确认请求后立即丢失状态 (例如崩溃并重启) 的示例, 因此稍后到达的分离响应会成为意外消息. 在这种情况下, 客户端使用 Reset 消息拒绝该可确认响应. 注意, 意外到达的 ACK 会被静默忽略.

Client  Server
| |
| |
+----->| Header: GET (T=CON, Code=0.01, MID=0x7d39)
| GET | Token: 0x64
| | Uri-Path: "temperature"
CRASH |
| |
|<- - -+ Header: (T=ACK, Code=0.00, MID=0x7d39)
| |
| |
|<-----+ Header: 2.05 Content (T=CON, Code=2.05, MID=0xad7c)
| 2.05 | Token: 0x64
| | Payload: "22.3 C"
| |
| |
+- - ->| Header: (T=RST, Code=0.00, MID=0xad7c)
| |

图 21: 可确认请求; 分离响应 (意外到达)

图 22 展示了一个基本 GET 请求, 其中请求和响应都是不可确认 (Non-confirmable) 的, 因此二者都可能在无通知的情况下丢失.

Client  Server
| |
| |
+----->| Header: GET (T=NON, Code=0.01, MID=0x7d40)
| GET | Token: 0x75
| | Uri-Path: "temperature"
| |
| |
|<-----+ Header: 2.05 Content (T=NON, Code=2.05, MID=0xad7d)
| 2.05 | Token: 0x75
| | Payload: "22.3 C"
| |

图 22: 不可确认请求; 不可确认响应

在图 23 中, 客户端向组播地址发送不可确认 GET 请求: 链路本地作用域内的所有节点. 该链路上有 3 个服务器: A、B 和 C. 服务器 A 和 B 拥有匹配资源, 因此返回不可确认的 2.05 (Content) 响应. B 发送的响应丢失. C 没有匹配资源, 因此发送不可确认的 4.04 (Not Found) 响应.

Client  ff02::1  A  B  C
| | | | |
| | | | |
+------>| | | | Header: GET (T=NON, Code=0.01, MID=0x7d41)
| GET | | | | Token: 0x86
| | | | Uri-Path: "temperature"
| | | |
| | | |
|<------------+ | | Header: 2.05 (T=NON, Code=2.05, MID=0x60b1)
| 2.05 | | | Token: 0x86
| | | | Payload: "22.3 C"
| | | |
| | | |
| X------------+ | Header: 2.05 (T=NON, Code=2.05, MID=0x01a0)
| 2.05 | | | Token: 0x86
| | | | Payload: "20.9 C"
| | | |
| | | |
|<------------------+ Header: 4.04 (T=NON, Code=4.04, MID=0x952a)
| 4.04 | | | Token: 0x86
| | | |

图 23: 不可确认请求 (组播); 不可确认响应