我有一个CoAP服务器和我使用Californium库用Java编写的客户端。我可以通过客户端或使用带有铜(Cu)扩展的Firefox从服务器获取资源。我想获得从服务器获得的响应的总大小。我已经可以获得有效载荷的大小,但我想要总的消息大小。如果我通过代码或工具完成此任务并不重要。到目前为止,我一直无法在谷歌上找到实现这一目标的方法。
答案 0 :(得分:2)
这取决于你想要得到什么。
我建议使用wireshark,捕获并分析数据包:
据我所知,没有干净而直接的方法来实现这一目标。
有一些解决方法。
您可以包装一个连接器并将端点显式设置为客户端(以及服务器,但我显示的是客户端版本):
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和令牌将特定响应与总长度相关联。
这里的一个陷阱是你必须使用一些全局存储。
我不建议将其用于生产。 除了一些罕见的情况,例如打印一些包信息+长度。也可以通过启用一些适当的Californium记录器水平来实现。
所以,从字面上看,这是一种不好的做法。
您可以使用MessageLengthTracer类实现 org.eclipse.californium.core.network.interceptors.MessageInterceptor 接口。
client.setEndpoint(...);
client.endpoint().setMessageTracer(new MessageLengthTracer());
在那里,您可以使用 org.eclipse.californium.core.network.serialization.DataSerializer 序列化消息,其技术类似于之前的解决方法,并获取其长度。
虽然,这也是一种解决方法,但存在两个陷阱 - 可能的长度不准确和双序列化工作。
P.S。如果有人说我错了,我会很高兴并指出我干净利落的方式。