linuxlab.io
Учебники▾
  • Линукс и сети
    Файловая система, процессы, TCP/IP, BGP и OSPF
    →
  • Terraform и IaC
    HCL, state, plan/apply на sandbox LocalStack
    →
  • Git и GitHub
    Объектная модель, plumbing, ветвление, GitHub Actions
    →
Все учебники →
ЦеныО платформеВойтиСоздать аккаунт
/
  • Введение
  • Уроки
  • How it works
  • Симулятор
  • База знаний
  • Собеседование
Index
Categories
All entries
Footer
linuxlab-УчебникиЦеныО платформеКонфиденциальность и куки
Copyright © 2026 LinuxLab. Все права защищены.
home/linux/kb/Сеть: L4 и выше/coap

kb/network-l4 ── Сеть: L4 и выше ── beginner

CoAP - REST для constrained-устройств поверх UDP

CoAP - REST поверх UDP для маломощных IoT-устройств. 4-байтный header, GET/POST/PUT/DELETE, response codes как HTTP. Observe для notifications. DTLS для security. Применяется в LwM2M, Thread.

view as markdownaka: coap, coap-protocol, dtls, constrained-application-protocol

Зачем CoAP

Классический HTTP не работает на сильно constrained устройствах:

  • Маленькая микроконтроллерная RAM (десятки KB)
  • Battery-powered (нельзя держать TCP-сессии)
  • Lossy radio (LoRa, Zigbee, Thread mesh)
  • Не во всех есть IPv4-stack полностью

HTTP-парсер - сложный, headers большие (даже минимальный GET ~80 байт).

CoAP (Constrained Application Protocol, RFC 7252, 2014) - REST-like protocol специально для них. Поверх UDP, минимальный header, REST-семантика. Сделан так, чтобы device мог быть и client, и server одновременно.

Применения:

  • LwM2M (Lightweight M2M от OMA) - device management поверх CoAP
  • Thread (mesh-сеть для smart home) - CoAP в native protocol stack
  • ZigBee Pro - CoAP опция
  • OMA Lightweight Object Tree - сенсоры/actuators в LwM2M
  • Energy management в HEMS

CoAP vs HTTP - семантика

HTTPCoAP
TCPUDP (TCP-вариант RFC 8323)
Text headersBitfields, options
Headers ~80+ байтHeader ~4 байта
Methods GET/POST/...Те же 4 + блок-расширения
URLsURIs, Uri-Path/Uri-Query options
Response codes 200/404/...Кодировано по 5.x.y (5 классов × 32)
Stateless request/responseConfirmable / Non-confirmable
EventSource/SSE/WebSocket для pushObserve-pattern native

Идея: один и тот же ментальный модель (URL, метод, status), но ужатый под радио и мелкое железо.

Wire format

Минимальный CoAP-header - 4 байта:

 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
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|Ver| T |  TKL  |      Code     |          Message ID           |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|   Token (if any, TKL bytes) ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|   Options (if any) ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|1 1 1 1 1 1 1 1|    Payload (if any) ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  • Ver - версия (1)
  • T - тип сообщения: CON (confirmable), NON (non-conf), ACK, RST
  • TKL - длина token (0-8 байт)
  • Code - 8 бит, формат c.dd (3 бит class + 5 бит detail). Method: 0.01=GET, 0.02=POST, 0.03=PUT, 0.04=DELETE Response: 2.05=Content (≈200), 4.04=Not Found (≈404), 5.00=Internal Error
  • Message ID - 16-битный, для duplicate detection
  • Token - 0-8 байт, для request-response correlation (отличается от Message ID - один request может породить много responses через observe)
  • Options - URI path, content-format, ETag, Observe, ...
  • 0xFF - разделитель payload

Минимальный GET с пустым payload - 4 байта + URI options.

Confirmable vs Non-confirmable

CoAP - поверх UDP, нет встроенной reliability. Решение - тип сообщения:

CON (Confirmable) - reliable

client ──CON GET /sensor (mid=42)──► server
client ◄──ACK 2.05 Content (mid=42)── server

Ack обязателен. Без ack - retry (exp backoff): 2s, 4s, 8s, 16s, 32s

  • максимум 5 попыток (RFC 7252).

Если piggyback - сервер шлёт ACK с уже готовым response (одна посылка).

NON (Non-confirmable) - fire-and-forget

client ──NON GET /sensor (mid=42)──► server

Никакого ack. Если потерян - потерян. Для high-rate телеметрии где одно потеряное сообщение неважно.

Похоже на mqtt QoS 0 (NON) и QoS 1 (CON).

Methods и status codes

Methods (RFC 7252):

  • GET 0.01 - получить ресурс
  • POST 0.02 - создать
  • PUT 0.03 - обновить
  • DELETE 0.04 - удалить
  • расширения:
  • FETCH 0.05 (RFC 8132) - GET с body (для сложных queries)
  • PATCH 0.06, iPATCH 0.07 (RFC 8132)

Response classes:

  • 2.xx - Success: 2.01 Created, 2.02 Deleted, 2.03 Valid (ETag), 2.04 Changed, 2.05 Content
  • 4.xx - Client error: 4.00 Bad Request, 4.04 Not Found, 4.05 Method Not Allowed, 4.06 Not Acceptable, 4.13 Request Entity Too Large
  • 5.xx - Server error: 5.00 Internal, 5.03 Service Unavailable

URI и options

URI типа coap://gw.example/sensors/temp?units=C. На проводе:

  • Uri-Host (option 3) = "gw.example"
  • Uri-Path (option 11) = "sensors", "temp" (по сегментам)
  • Uri-Query (option 15) = "units=C"

Опции typed - 28 предопределённых, кастомные через elective/critical flag в опции number.

Каждая option encode'ится с delta-кодированием от предыдущей - компактно.

Observe pattern - server-pushed updates

RFC 7641. Клиент посылает GET с Observe option = 0:

client ──GET /temperature, Observe=0──► server
client ◄──2.05 Content "21.5", Observe=1── server
client ◄──2.05 Content "21.6", Observe=2── server (через 30 сек)
client ◄──2.05 Content "21.7", Observe=3── server
...

Сервер шлёт push'ы каждый раз когда ресурс изменился (или по таймеру). Observe-counter монотонно растёт - помогает обнаружить потерянные/out-of-order responses.

Cancel - GET с Observe = 1 или просто RST в ответ на следующее.

Это CoAP-эквивалент EventSource/WebSocket для push'а - но без открытой сессии (UDP).

Block-wise transfer

Большие payloads через UDP - проблема (фрагментация, потеря). CoAP делит на блоки через Block1/Block2 options (RFC 7959):

Block1 = 0/1/512    означает: блок 0, more=1, размер 512

Клиент шлёт PUT блоками 0..N с Block1, последний с more=0. Сервер собирает.

Размер блока 16-1024 байта. Default - подбор под underlying MTU (обычно 64-256 для LoRa, 512-1024 для WiFi/Thread).

DTLS - security

CoAP сам не шифрует. DTLS (Datagram TLS, RFC 6347) - TLS-over-UDP (как [[tls-handshake|TLS]] но с retransmission и без strict ordering).

CoAP+DTLS = coaps:// на UDP/5684 (vs обычный coap:// на 5683).

Modes:

  • NoSec - plain CoAP (для labа)
  • PSK (Pre-Shared Key) - shared secret, легковесно для constrained
  • RPK (Raw Public Key) - cert без X.509 signature chain
  • Certificate - полный X.509 (как HTTPS)

PSK самый популярный в IoT - device shipped с factory key, broker знает.

Современные расширения:

  • OSCORE (RFC 8613) - object security, защита payload end-to-end даже через proxy
  • EDHOC (RFC 9528) - lightweight key exchange для PSK

CoAP vs MQTT

СвойствоCoAP[[mqtt|MQTT]]
ТранспортUDP (или TCP/TLS)TCP/TLS
Модельrequest-response (REST)publish-subscribe
Brokerне нуженобязателен
Pushobserve-patternsubscribe
Min header4 байта2 байта
ReliabilityCON ack/retryQoS 0/1/2
Multicastда (group communication)нет
Best forsensor query, RESTful APItelemetry, fan-out
StackREST-like, знакомыйспецифический
SecurityDTLSTLS (сложнее на mc)

В Thread/Matter - CoAP базовый. В classic IoT (industrial, mobile)

  • чаще MQTT.

Multicast - group communication

CoAP поддерживает IP multicast: одно request → все devices в multicast-группе отвечают. Для discovery, group control:

GET coap://[ff02::fd]:5683/.well-known/core
              ──► все CoAP-серверы в локальном link

HTTP такого нет. Полезно в smart home: "все лампы → off".

Только для NON-confirmable (CON через multicast логически невозможен).

Discovery - /.well-known/core

RFC 6690 - стандартный resource directory:

GET /.well-known/core
───►
◄─── 2.05
     </sensors/temp>;rt="temperature";if="sensor",
     </sensors/humidity>;rt="humidity";if="sensor",
     </actuators/led>;rt="light";if="actuator"

Application-level discovery - what resources, what types.

Когда что-то пошло не так

  • Запросы пропадают - UDP. Проверь firewall (5683/5684 UDP). Используй CON вместо NON чтобы видеть.
  • 4.13 Request Entity Too Large - payload > MTU. Используй Block1.
  • DTLS handshake fail - PSK не совпадает или TLS-версия mismatch (CoAP DTLS обычно DTLS 1.2). openssl s_client -dtls1_2.
  • Observe не работает после NAT - NAT-binding истёк, server шлёт в "никуда". Делай keepalive (CON GET изредка) или сильно короче interval.
  • Sequence number wrap - Observe counter 24-bit, при wrap логика может ошибаться. Большинство реализаций обработали.
  • Multicast не доходит - kernel не routing'ит multicast по дефолту. ip route add 224.0.0.0/4 dev eth0. И уровень link должен поддерживать (WiFi - часто фильтрует).

Где почитать

  • https://datatracker.ietf.org/doc/html/rfc7252 - оригинальный CoAP
  • https://coap.technology/ - инструменты, статьи
  • https://github.com/eclipse/californium (Java) - reference implementation
  • https://github.com/obgm/libcoap (C) - для embedded

§ команды

bash
coap-client -m get coap://localhost/.well-known/core

Discovery: список ресурсов на CoAP-сервере (libcoap CLI)

bash
coap-client -m get coap://gw.example/sensors/temp

Простой GET-запрос на ресурс

bash
coap-client -m put -e '21.5' coap://gw/actuators/setpoint

PUT с payload - обновить ресурс

bash
coap-client -s 60 -m get coap://gw/sensors/temp

Subscribe (observe) - 60 секунд получать notifications

bash
coap-client -m get coaps://gw/secret -k mySecretKey -u myIdentity

DTLS+PSK - identity и pre-shared key

bash
coap-client -m get -B 64 coap://gw/big_resource

Block-wise transfer с размером блока 64 байта

bash
tshark -Y coap -i eth0

Wireshark dissector для CoAP - видно типы, options, observe

bash
nc -u localhost 5683

Открыть UDP-сокет к CoAP-порту - можно посмотреть raw bytes

§ см. также

  • udp-basicsUDP - User Datagram ProtocolUDP - простой протокол доставки датаграмм без установки соединения, без ретрансмитов, без гарантии порядка. Заголовок 8 байт. Применение: DNS, DHCP, QUIC, VoIP, любой случай когда задержка важнее надёжности.
  • mqttMQTT - publish/subscribe для IoT и mobile pushMQTT - lightweight pub/sub поверх TCP. Topics с wildcards, QoS 0/1/2, retained messages, last will. Малый overhead (2 байта min header). Брокер обязателен (mosquitto/EMQX/HiveMQ). Применение: IoT, telemetry, mobile push.
  • tls-handshakeTLS handshakeTLS - слой шифрования поверх TCP. Перед передачей данных стороны делают handshake: обмениваются ключами, проверяют сертификат, выбирают cipher.
  • portПорт - как несколько сервисов делят один IP16-битное число (0-65535), идентифицирует **процесс-получатель** на хосте. IP говорит куда (хост), порт - кому (процессу). 80 - HTTP, 443 - HTTPS, 22 - SSH.
  • http-protocolHTTP/1.1, HTTP/2, HTTP/3HTTP/1.1 - текстовый протокол с keep-alive. HTTP/2 - бинарный с мультиплексированием в одном TCP-соединении. HTTP/3 = HTTP/2-семантика поверх QUIC/UDP без TCP-head-of-line blocking.
Footer
linuxlab-
Copyright © 2026 LinuxLab. Все права защищены.
Учебники
Цены
О платформе
Конфиденциальность и куки