CoAP是什么
CoAP是受限制的应用协议(Constrained Application Protocol)的代名词。由于通常物联网设备都是资源限制型的,有限的CPU能力,有限RAM,有限的flash,有限的网络带宽, 针对此类特殊场景,COAP协议借鉴了HTTP协议机制并简化了协议包格式。 CoAP是一种应用层协议,它运行于UDP协议之上而不是像HTTP那样运行于TCP之上。CoAP协议非常小巧,最小的数据包仅为4字节。
COAP协议特点
- 基于消息模型,定义了4个消息类型,以消息为数据通信载体,通过交换网络消息来实现设备间数据通信对CoAP Server云端设备资源操作都是通过请求与响应机制来完成,类似HTTP,设备端可通过4个请求方法(GET, PUT, POST, DELETE)
- 对服务器端资源进行操作。 请求与响应的数据包都是放在CoAP消息里面进行传输的基于消息的双向通信(M2M),CoAP Client与CoAP server双方都可以独立向对方发送请求.双方可当client或者server角色。
- 协议包轻量级,最小长度仅为4B。
- 支持可靠传输,数据重传,块传输。 确保数据可靠到达。
- 支持IP多播, 即可以同时向多个设备发送请求(比如CoAP client搜索CoAP Server)
- 非长连接通信,适用于低功耗物联网场景
CoAP的URL
在HTTP的世界中,RESTFul协议由于其简单性和适用性,在WEB应用中越来越受欢迎,这样的道理同样适用于CoAP。一个CoAP资源可以被一个URI所描述,例如一个设备可以测量温度,那么这个温度传感器的URI被描述为:CoAP://machine.address:5683/sensors/temperature。请注意,CoAP的默认UDP端口号为5683。
CoAP的请求和响应
HTTP 与 COAP协议都是通过4个请求方法(GET, PUT, POST, DELETE)对服务器端资源进行操作。 两者之间明显的区别在于HTTP是通过文本描述方式描述协议包内容,协议包里面会包含一些空格符,换行符等,协议包可读性很强。而COAP是通过定义 二进制各位段功能来描述协议包内容。 因此COAP协议包大小更小,更紧凑。COAP协议最小的协议包只有4B。 协议包需要经过解析后才能知道里面具体内容,另还有一个明显的区别是传统的HTTP协议是主机与web服务器之间是单向通信的(用websocket除外)。而CoAP系统中CoAP Client与CoAP server是可以双向通信,双方都可以主动向对方发送请求。
CoAP消息类型
CoAP采用与HTTP协议相同的请求响应工作模式。CoAP协议共有4中不同的消息类型。 CON——需要被确认的请求,如果CON请求被发送,那么对方必须做出响应。 NON——不需要被确认的请求,如果NON请求被发送,那么对方不必做出回应。 ACK——应答消息,接受到CON消息的响应。 RST——复位消息,当接收者接受到的消息包含一个错误,接受者解析消息或者不再关心发送者发送的内容,那么复位消息将会被发送。
CoAP消息结构
一个CoAP消息最小为4个字节,以下是CoAP协议不同部分的描述。 【版本Version】:类似于IPv6和IPv6,仅仅是一个版本号。 【消息类型Message Type】:CON,NON,ACK,RST。 【消息ID Message ID】:每个CoAP消息都有一个ID,在一次会话中ID总是保持不变。但在这个会话之后该ID会被回收利用。 【标记 Token】:标记是ID的另一种表现。 【选项 Options】:CoAP选项类似于HTTP请求头,它包括CoAP消息本身,例如CoAP端口号,CoAP主机和CoAP查询字符串等。 【负载Payload】:真正有用的被交互的数据。
Java开发框架可以使用eclipse californium maven
导入依赖包
<!--CoAP依赖--> <dependency> <groupId>org.eclipse.californium</groupId> <artifactId>californium-core</artifactId> <version>2.0.0-M7</version> </dependency> <dependency> <groupId>org.eclipse.californium</groupId> <artifactId>element-connector</artifactId> <version>2.0.0-M7</version> </dependency> <dependency> <groupId>org.eclipse.californium</groupId> <artifactId>scandium</artifactId> <version>2.0.0-M7</version> </dependency>
服务端
public class CoAPServer { public static void main(String[] args) { new CoAPServer().startServer(); } public void startServer(){ CoapServer server = new CoapServer(5683);//主机为localhost 端口为默认端口5683 server.add(new CommonHandler("car")); server.add(new CoapResource("hello")); server.start(); } class CommonHandler extends CoapResource { public CommonHandler(String name) { super(name); } @Override public void handleGET(CoapExchange exchange) { //重写处理GET请求的方法 System.out.println("收到Get请求,消息内容为:"+exchange.getRequestText()); exchange.respond(CoAP.ResponseCode.CONTENT, "OK"); } public void handlePOST(CoapExchange exchange) { System.out.println("收到Post请求,消息内容为:"+exchange.getRequestText()); exchange.respond(CoAP.ResponseCode.CONTENT,"OK"); } //下面还可以重写处理DELETE、UPDATE的方法 } }
客户端
public class CoAPClient { public static void main(String[] args) throws URISyntaxException { new CoAPClient().startListen(); } public void startListen() throws URISyntaxException { new Thread(new SendMessageThread(new URI("localhost:5683/car"))).start();//创建一个资源请求hello资源,注意默认端口为5683 } class SendMessageThread implements Runnable { URI uri; SendMessageThread(URI uri) throws URISyntaxException { this.uri = uri; } @Override public void run() { CoapClient client = new CoapClient(uri); /** 反复将输入发送到服务端 */ while (true) { BufferedReader in = new BufferedReader(new InputStreamReader(System.in));// 包装控制台输入流 try { String msg = in.readLine(); CoapResponse response = client.post(msg, MediaTypeRegistry.TEXT_PLAIN); if(response !=null){ System.out.println("Status Code: "+response.getCode()); //打印请求状态码 System.out.println("选项参数: "+response.getOptions()); //选项参数 System.out.println("文本内容: "+response.getResponseText()); //获取内容文本信息 System.out.println("\nAdvanced\n"); // System.out.println(Utils.prettyPrint(response)); //打印格式良好的输出 } } catch (IOException e) { e.printStackTrace(); } } } } }
ref.
https://en.wikipedia.org/wiki/Constrained_Application_Protocol
https://blog.csdn.net/xukai871105/article/details/17734163
https://github.com/eclipse/californium/