简体   繁体   中英

Determine total CoAP message size

I have both a CoAP Server and Client I wrote in Java with the Californium library. I can get resources from the server both through the client or with Firefox with the Copper(Cu) extension. 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.

It depends on what you want to get.

1) If you just want to discover some footprints.

I'd recommend to use wireshark, capture and analyze the packets:

https://www.wireshark.org

2) If you want to use the lengths programatically

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):

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:

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.

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.

So, it is a bad practice, literally.

MessageTracer and serializing Messages

You may implement a org.eclipse.californium.core.network.interceptors.MessageInterceptor interface, say, with a class MessageLengthTracer.

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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