繁体   English   中英

确定CoAP消息的总大小

[英]Determine total CoAP message size

我既有CoAP服务器,也有用Californium库用Java写的客户端。 我可以通过客户端或使用带有Copper(Cu)扩展名的Firefox从服务器获取资源。 我想获得从服务器获得的响应的总大小。 我已经可以得到有效负载的大小,但是我想要消息的总大小。 我是通过代码还是通过工具完成此操作都没有关系。 到目前为止,我一直无法在Google上找到实现此目标的方法。

这取决于您想要得到什么。

1)如果您只想发现一些足迹。

我建议使用wireshark,捕获并分析数据包:

https://www.wireshark.org

2)如果要以编程方式使用长度

据我所知,没有干净直接的方法来实现这一目标。

有一些解决方法。

连接器

您可以包装一个Connector并为客户端(以及服务器)显式设置一个端点,但我正在显示客户端版本:

CoapClient client = new CoapClient(new URI(uri));
client.setEndpoint(
    new CoapEndpoint(
        new InterceptingUDPConnector(
            new UDPConnector(
                new InetSocketAddress(
                    portNumber
                )
            )
        ),
        NetworkConfig.getStandard()
    )
)

这是连接器包装:

public class InterceptingUDPConnector implements Connector {
    private final Connector origin;

    public InterceptingUDPConnector(Connector origin) {
        this.origin = origin;
    }

    @Override
    public void send(RawData msg) {
        System.out.println("Length:" + msg.getSize());
        origin.send(msg);
    }

    @Override
    public void setRawDataReceiver(RawDataChannel messageHandler) {
        RawDataChannel decodingChannel = raw -> {
            System.out.println("Length: " + raw.getSize())
            messageHandler.receiveData(raw);
        };
        origin.setRawDataReceiver(decodingChannel);
    }

    @Override
    public void start() throws IOException {
        origin.start();
    }

    @Override
    public void stop() { origin.stop();
    }

    @Override
    public void destroy() { origin.destroy();
    }

    @Override
    public InetSocketAddress getAddress() {
        return origin.getAddress();
    }
}

但是,很难将这些长度和响应关联起来。

我使用以下类来解析RawData:

import org.eclipse.californium.core.coap.Message;
import org.eclipse.californium.core.network.serialization.DataParser;
import org.eclipse.californium.elements.RawData;

public class ParsedPacket {
    private final RawData packet;

    public ParsedPacket(RawData packet) {
        this.packet = packet;
    }

    @Override
    public String toString() {
        Message msg = null;
        DataParser parser = new DataParser(packet.getBytes());
        if (parser.isEmpty()) {
            msg = parser.parseEmptyMessage();
        } else if (parser.isRequest()) {
            msg = parser.parseRequest();
        } else if (parser.isResponse()) {
            msg = parser.parseResponse();
        }
        return (msg == null) ? "" : msg.toString();
    }
}

这样,您可以使用例如MID和令牌将特定的响应和总长度关联起来。

这里的一个陷阱是您必须为此使用一些全局存储。

我不建议将其用于生产。 除少数情况外,例如打印一些数据包信息和长度。 也可以通过启用一些适当的Calibernium记录器级别来覆盖。

因此,从字面上看,这是一个不好的做法。

MessageTracer和序列化消息

例如,您可以使用MessageLengthTracer类实现org.eclipse.californium.core.network.interceptors.MessageInterceptor接口。

client.setEndpoint(...);
client.endpoint().setMessageTracer(new MessageLengthTracer());

在那里,您可以使用org.eclipse.californium.core.network.serialization.DataSerializer序列化消息,其技术类似于先前的解决方法,并获取其长度。

虽然,这也是一种解决方法,但有两个陷阱-可能的长度错误和双重序列化工作。

附注:如果有人说我错了,并指出要这样做的干净方法,我会很高兴。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM