美文网首页MQTT&CoAP等
Coap协议和Californium框架使用示例

Coap协议和Californium框架使用示例

作者: knarf | 来源:发表于2020-08-06 20:12 被阅读0次

Coap协议和Californium框架使用示例

本文主要讲述Coap协议和专门针对Coap协议开发的Californium框架,文章分成3部分,

1. Coap协议介绍

2. Californium框架介绍

3. Californium框架的使用示例,含代码

文章的第一和第二部分在网上有很多文章,内容都差不多,但是关于Californium的使用,网上很少有资料涉及,感兴趣的读者可以重点关注下。进入正题。

一、Coap协议介绍

Coap(Constrained Application Protocol)是一种在物联网世界的类web协议,它的详细规范定义在 RFC 7252。COAP名字翻译来就是“受限应用协议”,顾名思义,使用在资源受限的物联网设备上。物联网设备的ram,rom都通常非常小,运行TCP和HTTP是不可以接受的。

1.1  COAP协议特点

COAP网络传输层采用UDP。

它基于REST,server的资源地址和互联网一样也有类似url的格式,客户端同样有POST,   

      GET,PUT,DELETE方法来访问server,对HTTP做了简化。

COAP是二进制格式的,HTTP是文本格式的,COAP比HTTP更加紧凑。

轻量化,COAP最小长度仅仅4B。

支持可靠传输,数据重传,块传输。

支持IP多播, 即可以同时向多个设备发送请求。

非长连接通信,适用于低功耗物联网场景。

1.2  COAP协议消息类型

COAP协议有4种消息类型

CON—— 需要被确认的请求,如果CON请求被发送,那么对方必须做出响应。这有点像TCP,对方必须给确认收到消息,用以可靠消息传输。

NON—— 不需要被确认的请求,如果NON请求被发送,那么对方不必做出回应。这适用于消息会重复频繁的发送,丢包不影响正常操作。这个和UDP很像。用以不可靠消息传输。

ACK —— 应答消息,对应的是CON消息的应答。

RST —— 复位消息,可靠传输时候接收的消息不认识或错误时,不能回ACK消息,必须回RST消息。

1.3 COAP消息格式

1.3.1 消息头(HEAD)

第一行是消息头,必须有,固定4个byte。

Ver : 2bit, 版本信息,当前是必须写0x01。

T: 2bit, 消息类型,包括 CON, NON. ACK, RST这4种。

TKL: 4bit,token长度, 当前支持0~8B长度,其他长度保留将来扩展用。

Code:8bit,分成前3bit(0~7)和后5bit(0~31),前3bit代表类型。 0代表空消息或者请求码, 2开头代表响应码,取值如下:

1 0.00 Indicates an Empty message

2 0.01-0.31 Indicates a request.

3 1.00-1.31 Reserved

4 2.00-5.31 Indicates a response.

5 6.00-7.31 Reserved

Message ID:16bit, 代表消息MID,每个消息都有一个ID ,重发的消息MID不变

token(可选)用于将响应与请求匹配。 token值为0到8字节的序列。 ( 每条消息必须带有一个标记, 即使它的长度为零)。 每个请求都带有一个客户端生成的token, 服务器在任何结果响应中都必须对其进行回应。token类似消息ID,用以标记消息的唯一性。token还是消息安全性的一个设置,使用全8字节的随机数,使伪造的报文无法获得验证通过。

1.3.2 option

请求消息与回应消息都可以0~多个options。 主要用于描述请求或者响应对应的各个属性,类似参数或者特征描述,比如是否用到代理服务器,目的主机的端口等。

1.3.3 payload

实际携带数据内容,若有,前面加payload标识符“0xFF”,如果没有payload标识符,那么就代表这是一个0长度的payload。如果存在payload标识符但其后跟随的是0长度的payload,那么必须当作消息格式错误处理。

1.4 COAP的请求码(requests)和响应码(responses)

【0.01】GET方法——用于获得某资源

【0.02】POST方法——用于创建某资源

【0.03】PUT方法——用于更新某资源

【0.04】DELETE方法——用于删除某资源

1.5 CoAP的URL

coap的url和HTTP的有很相似的地方,开头是“coap”对应“http”或者“coaps”对应“https”。

HTTP的默认端口是tcp 80,coap的默认端口是udp 5683(coaps是5684)。

二、Californium框架介绍

Californium框架是一款基于Java实现的Coap技术框架,该项目实现了Coap协议的各种请求响应定义,支持CON/NON不同的可靠性传输模式。Californium 基于分层设计且高度可扩展

Californiium 定义了三层架构

1 网络层,负责处理端口监听,网络数据收发;

2 协议层,负责Coap协议数据包解析及封装,实现消息的路由、可靠性传输、Token处理、观察者模型等等;

3 逻辑层,负责 Resource定义和映射,一个Resource 对应一个URL,可独立实现Coap 请求处理。为了便于理解,可以将resource是为一个servlet或者controller。

对于我们来讲,开发工作主要在逻辑层。

三层架构中都可以支持独立的线程池,其中网络层与协议层的线程池保持独立;

逻辑层可为每个Resource指定独立的线程池,并支持父级继承的机制,即当前Resource若没有定义则沿用父级Resource线程池;

若逻辑层未指定线程池,则默认使用协议层的线程池。

2.1 Californium主要接口介绍

Californium框架的使用并不复杂,我们主要是调用逻辑层的一些类,最常用的一些类和接口如下:

CoapClient:客户端的入口,客户端通过实现CoapClient向服务端发送数据。

CoapServer:服务端的入口,启动服务端,接收客户端传送的数据。

Endpoint:定义为一个端点,通常与一个IP和端口对应,其屏蔽了client和server交互时的网络传输细节。对于client来说,Endpoint代表通讯的服务端地址端口;而对于server来说则代表了绑定监听的地址及端口。CoapEndpoint实现了Endpoint接口。

Exchange:Exchange描述了请求-响应模型,一个Exchange会对应一个Request,相应的Response,以及当前的Endpoint。

CoapResource:最终处理消息的类,通过继承CoapResource类来实现处理客户端发来的请求,通过重写相应的方法处理GET,POST等请求,实现Resource的时候需要指定Resource的名字,这个名字很重要,客户端请求的时候在uri中需要带上Resource的名字,这样框架才会将请求指向对应的Resource。

三、Californium框架的使用示例

示例介绍了一个简单的框架的应用,客户端向服务端发送一段json串,服务端接收并返回接收成功消息。代码基于JDK1.8。

客户端代码

Client类

import java.io.IOException;

import java.net.URI;

import java.net.URISyntaxException;

import org.eclipse.californium.core.CoapClient;

import org.eclipse.californium.core.CoapResponse;

import org.eclipse.californium.elements.exception.ConnectorException;

public class Client {

       URI uri = null;

       CoapClient coapClient = null;

       String body = "";

       public void init() throws URISyntaxException{

        // define the ip and resource name here, ‘test’ is the resource name

              uri = new URI("coap://192.168.56.2:5683/test");

              coapClient = new CoapClient(uri);

       }

       // send with post

       public void sendPost() throws ConnectorException, IOException {

              // the first arg is the request body

              // the second arg is the format id of the body, 0-text|50-json

              // refer to http://www.iana.org/assignments/core-parameters/core-parameters.xhtml#content-formats to get the format id

              CoapResponse response = coapClient.post(this.body.getBytes(), 50);

              System.out.println("the respnse code is "+response.getCode());

              System.out.println("the respnse body is "+response.getResponseText());

       }

       public void setBody(String body) {

              this.body = body;

       }

}

Client 启动类

import java.io.IOException;

import java.net.URISyntaxException;

import org.eclipse.californium.elements.exception.ConnectorException;

import com.ericsson.gpsInterface.test.Client;

import com.sun.org.apache.xml.internal.utils.URI.MalformedURIException;

public class ClientApp {

       public static void main(String[] args) throws ConnectorException, IOException, InterruptedException, URISyntaxException {

              String body = "{\"id\":\"1\",\"name\":\"tom\"}";

              Client myclient = new Client();

              myclient.init();

              myclient.setBody(body);

              System.out.println("message sent");

              for(int i=0;i<10;i++) {

                     myclient.sendPost();

                     Thread.sleep(100);

              }

       }

}

服务端代码

Server代码

import java.net.InetAddress;

import java.net.InetSocketAddress;

import java.net.UnknownHostException;

import org.eclipse.californium.core.CoapServer;

import org.eclipse.californium.core.network.CoapEndpoint;

import org.eclipse.californium.core.network.config.NetworkConfig;

public class Server extends CoapServer{

       public void myAddEndPoint() throws UnknownHostException {

// get the NetworkConfig object of californium

              NetworkConfig config = NetworkConfig.getStandard();

              String ip = "0.0.0.0";

              InetAddress addr = InetAddress.getByName(ip);

        //5683 is the default port

              InetSocketAddress bindToAddress = new InetSocketAddress(addr,5683);

// create a new endpoint

              CoapEndpoint.Builder builder = new CoapEndpoint.Builder();

              builder.setInetSocketAddress(bindToAddress);

              builder.setNetworkConfig(config);

// add the endpoint to the server

              super.addEndpoint(builder.build());

       }

       public void start() {

        // add the resource to the server, the resource name here is ‘test’ which is corresponding

// to the uri in the client

              super.add(new TestResource("test"));

              try {

                     this.myAddEndPoint();

              } catch (UnknownHostException e) {

                     // TODO Auto-generated catch block

                     e.printStackTrace();

              }

              System.out.println("sever start");

              super.start();

       }

}

TestResource 代码

import org.eclipse.californium.core.CoapResource;

import org.eclipse.californium.core.coap.CoAP.ResponseCode;

import org.eclipse.californium.core.server.resources.CoapExchange;

public class TestResource extends CoapResource{

      public TestResource(String name) {

// define the resource name, also the url path

              super(name);

              getAttributes().setTitle(name);

      }

      @Override

      public void handleGET(CoapExchange exchange) {

System.out.println("get start");

              exchange.respond("got");

                    }

      @Override

      public void handlePOST(CoapExchange exchange) {

              System.out.println("post start");

              String result = exchange.getRequestText();

              System.out.println("the received text:"+result);

              //exchange.respond(ResponseCode.CHANGED);

              exchange.respond(ResponseCode.CHANGED, "good");

      }

}

Server启动类代码

public class App{   

public static void main( String[] args )   

{        Server myserver = new Server();       

          myserver.start();   

}

相关文章

网友评论

    本文标题:Coap协议和Californium框架使用示例

    本文链接:https://www.haomeiwen.com/subject/lsmtdktx.html