简体   繁体   English

确定CoAP消息的总大小

[英]Determine total CoAP message size

I have both a CoAP Server and Client I wrote in Java with the Californium library. 我既有CoAP服务器,也有用Californium库用Java写的客户端。 I can get resources from the server both through the client or with Firefox with the Copper(Cu) extension. 我可以通过客户端或使用带有Copper(Cu)扩展名的Firefox从服务器获取资源。 I want to get the total size of the response i get from the server. 我想获得从服务器获得的响应的总大小。 I can get the size of the payload already, but I want the total message size. 我已经可以得到有效负载的大小,但是我想要消息的总大小。 It doesn't matter if I accomplish this through code or with a tool. 我是通过代码还是通过工具完成此操作都没有关系。 So far i have been unable to find on Google a way to accomplish this. 到目前为止,我一直无法在Google上找到实现此目标的方法。

It depends on what you want to get. 这取决于您想要得到什么。

1) If you just want to discover some footprints. 1)如果您只想发现一些足迹。

I'd recommend to use wireshark, capture and analyze the packets: 我建议使用wireshark,捕获并分析数据包:

https://www.wireshark.org https://www.wireshark.org

2) If you want to use the lengths programatically 2)如果要以编程方式使用长度

As far as I know there is no clean and direct way to achieve this. 据我所知,没有干净直接的方法来实现这一目标。

There is some workarounds. 有一些解决方法。

Connector 连接器

You may wrap a Connector and explicitly set an endpoint to the client (and server as well, but I'm showing a client version): 您可以包装一个Connector并为客户端(以及服务器)显式设置一个端点,但我正在显示客户端版本:

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

Here is the connector wrapper: 这是连接器包装:

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();
    }
}

However, it is hard to associate these lengths and responses. 但是,很难将这些长度和响应关联起来。

I use the following class to parse the RawData: 我使用以下类来解析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();
    }
}

With that, you may associate a particular response and the overall length using, for example MID and token. 这样,您可以使用例如MID和令牌将特定的响应和总长度关联起来。

A pitfall here is that you have to use some global storage for that. 这里的一个陷阱是您必须为此使用一些全局存储。

I don't recommend using it for production. 我不建议将其用于生产。 Except some rare cases eg print some packet info + length. 除少数情况外,例如打印一些数据包信息和长度。 Which also maybe covered by enabling some appropriate Californium logger level as well. 也可以通过启用一些适当的Calibernium记录器级别来覆盖。

So, it is a bad practice, literally. 因此,从字面上看,这是一个不好的做法。

MessageTracer and serializing Messages MessageTracer和序列化消息

You may implement a org.eclipse.californium.core.network.interceptors.MessageInterceptor interface, say, with a class MessageLengthTracer. 例如,您可以使用MessageLengthTracer类实现org.eclipse.californium.core.network.interceptors.MessageInterceptor接口。

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

There you can serialize messages using org.eclipse.californium.core.network.serialization.DataSerializer with technique similar to the previous workaround and get their lengths. 在那里,您可以使用org.eclipse.californium.core.network.serialization.DataSerializer序列化消息,其技术类似于先前的解决方法,并获取其长度。

Though, it is a workaround too and there is two pitfalls - possible length inaccuracy and double serialization work. 虽然,这也是一种解决方法,但有两个陷阱-可能的长度错误和双重序列化工作。

PS I will be glad if someone says I am wrong and point me to a clean way to do that. 附注:如果有人说我错了,并指出要这样做的干净方法,我会很高兴。

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

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