跳到主要内容

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: 不可确认请求 (组播); 不可确认响应