Определить общий размер сообщения CoAP

У меня есть и сервер CoAP, и клиент, который я написал на Java с библиотекой Californium. Я могу получать ресурсы с сервера как через клиента, так и через Firefox с расширением Copper (Cu). Я хочу получить общий размер ответа от сервера. Я уже могу получить размер полезной нагрузки, но мне нужен общий размер сообщения. Неважно, если я сделаю это с помощью кода или с помощью инструмента. До сих пор я не смог найти в Google способ сделать это.

1 ответ

Это зависит от того, что вы хотите получить.

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 и токен.

Подводный камень в том, что для этого вам нужно использовать глобальное хранилище.

Я не рекомендую использовать его для производства. За исключением некоторых редких случаев, например, выведите некоторую информацию о пакете + длину. Который также может быть покрыт включением некоторого соответствующего уровня регистратора Калифорнии.

Так что это буквально плохая практика.

MessageTracer и сериализация сообщений

Вы можете реализовать интерфейс org.eclipse.californium.core.network.interceptors.MessageInterceptor, скажем, с классом MessageLengthTracer.

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

Там вы можете сериализовать сообщения, используя org.eclipse.californium.core.network.serialization.DataSerializer с техникой, аналогичной предыдущему обходному пути, и получить их длины.

Однако это тоже обходной путь, и здесь есть две ловушки - возможная неточность длины и двойная сериализация.

PS Я буду рад, если кто-то скажет, что я неправ, и укажет мне чистый способ сделать это.

Другие вопросы по тегам