簡體   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