裸写coap客户端首先需要了解coap格式,它和http协议最大的区别是,它是字节协议,每个字节的不同都代表着不同的意义。
小沃通过传送门大致了解了coap的结构,如果大家想深入了解coap协议,请查看传送门。
话不多说,上代码:
#include <stdio.h> #include <stdint.h> #include <string.h> /* t 0:CON,1:NON,2:ACK,3:RST method 1:GET,2:POST,3:PUT,4:DELETE */ int coaprequest(uint8_t t, uint8_t method, uint8_t *token, uint8_t tokenlen, uint8_t *host, uint16_t hostlen, uint8_t *path, uint16_t pathlen, uint8_t *body, uint32_t bodylen, char *buff) { // coap请求 static uint16_t msgid = 0; int offset = 0; buff[offset] = 0x40; // ver为01 buff[offset] |= t << 4; if (tokenlen > 9) { return 0; } buff[offset] |= tokenlen; offset++; buff[offset++] = method; buff[offset++] = msgid >> 8; buff[offset++] = msgid; if (tokenlen > 0) { memcpy(buff+offset, token, tokenlen); offset += tokenlen; } // options if (hostlen > 0) { if (hostlen < 13) { // 这里添加一个Uri-Host buff[offset++] = 0x30 | hostlen; } else if (hostlen < 269) { buff[offset++] = 0x3d; buff[offset++] = hostlen - 13; } else { buff[offset++] = 0x3e; uint16_t tmplen = hostlen - 269; buff[offset++] = tmplen >> 8; buff[offset++] = tmplen; } memcpy(buff+offset, host, hostlen); offset += hostlen; } if (pathlen > 0) { if (pathlen < 13) { // 这里再添加一个Uri-Path,说明Uri-Path是13,也就是0x3+0x8,所以用0x80 buff[offset++] = 0x80 | pathlen; } else if (pathlen < 269) { buff[offset++] = 0x8d; buff[offset++] = pathlen - 13; } else { buff[offset++] = 0x8e; uint16_t tmplen = pathlen - 269; buff[offset++] = tmplen >> 8; buff[offset++] = tmplen; } memcpy(buff+offset, path, pathlen); offset += pathlen; } // body if (bodylen > 0) { buff[offset++] = 0xff; memcpy(buff+offset, body, bodylen); offset += bodylen; } return offset; } void main () { uint8_t buff[32*1024]; char *host = "www.worldflying.cn"; char *path = "/testcoap"; char *body = "{\"temp\":10.00000}"; int len = coaprequest(1, 2, "", 0, host, strlen(host), path, strlen(path), body, strlen(body), buff); printf("len:%d\n", len); for (int i = 0 ; i < len ; i++) { if (i % 16 == 0) { printf("\n"); } printf("%02x ", buff[i]); } }
文章作者:沃航科技