142 lines
3.4 KiB
Java
142 lines
3.4 KiB
Java
package biz.nellemann.jperf;
|
|
|
|
import java.io.IOException;
|
|
import java.nio.ByteBuffer;
|
|
import java.nio.charset.StandardCharsets;
|
|
import java.util.Arrays;
|
|
import java.util.Random;
|
|
|
|
import org.slf4j.Logger;
|
|
import org.slf4j.LoggerFactory;
|
|
|
|
/**
|
|
*
|
|
* Datagram consists of the following
|
|
* <p>
|
|
* <------------------------- HEADER 32 bytes --------------> <---------- DATA min 32 bytes -------->
|
|
* _long _int _int _long _long
|
|
* 8_bytes 4_bytes 4_bytes 8_bytes 8_bytes
|
|
* MAGIC-ID TYPE LENGTH CUR_PKT MAX_PKT
|
|
*
|
|
*/
|
|
|
|
public class Datagram {
|
|
|
|
final Logger log = LoggerFactory.getLogger(Datagram.class);
|
|
|
|
private final Random random = new Random();
|
|
|
|
private final int HEADER_LENGTH = 32;
|
|
|
|
private final byte[] MAGIC_ID = "jPerfTok".getBytes(StandardCharsets.UTF_8); // Must be 8-bytes
|
|
|
|
private final int type;
|
|
private final int length;
|
|
private final int realLength;
|
|
private final long curPkt;
|
|
private final long maxPkt;
|
|
private final byte[] data;
|
|
|
|
|
|
/**
|
|
* Create new empty datagram
|
|
* @param type
|
|
* @param length
|
|
* @param currentPkt
|
|
*/
|
|
public Datagram(int type, int length, long currentPkt, long maxPkt) {
|
|
|
|
log.debug("Datagram() - of type: {}, length: {}, sequence: {}", type, length, currentPkt, maxPkt);
|
|
|
|
this.type = type;
|
|
this.length = length;
|
|
this.curPkt = currentPkt;
|
|
this.maxPkt = maxPkt;
|
|
|
|
if(type == DataType.DATA.getValue()) {
|
|
realLength = length;
|
|
data = new byte[length - HEADER_LENGTH];
|
|
} else {
|
|
realLength = HEADER_LENGTH * 2;
|
|
data = new byte[HEADER_LENGTH * 2];
|
|
}
|
|
|
|
//random.nextBytes(data);
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
* Assemble datagram from payload
|
|
* @param payload
|
|
*/
|
|
public Datagram(byte[] payload) throws IOException {
|
|
|
|
log.debug("Datagram() magic ID is: {} bytes long and contains: {}", MAGIC_ID.length, MAGIC_ID.toString());
|
|
|
|
ByteBuffer buffer = ByteBuffer.wrap(payload);
|
|
byte[] id = new byte[8];
|
|
buffer.get(id);
|
|
if(!Arrays.equals(id, MAGIC_ID)) {
|
|
log.warn("Datagram() - magic ID does not match!");
|
|
throw new IOException();
|
|
}
|
|
|
|
// Order is importent when assembling header fields like this
|
|
type = buffer.getInt();
|
|
length = buffer.getInt();
|
|
curPkt = buffer.getLong();
|
|
maxPkt = buffer.getLong();
|
|
|
|
realLength = length;
|
|
if(type == DataType.DATA.getValue()) {
|
|
data = new byte[length - HEADER_LENGTH];
|
|
buffer.get(data, 0, data.length);
|
|
} else {
|
|
data = new byte[HEADER_LENGTH * 2];
|
|
}
|
|
}
|
|
|
|
|
|
public int getLength() {
|
|
return length;
|
|
}
|
|
|
|
public int getRealLength() {
|
|
return realLength;
|
|
}
|
|
|
|
public byte[] getPayload() throws IOException {
|
|
|
|
log.debug("getPayload() - with type: {}, length: {}, sequence: {}", type, length, curPkt);
|
|
ByteBuffer buffer = ByteBuffer.allocate(data.length + HEADER_LENGTH);
|
|
|
|
// Order is important
|
|
buffer.put(MAGIC_ID);
|
|
buffer.putInt(type);
|
|
buffer.putInt(length);
|
|
buffer.putLong(curPkt);
|
|
buffer.putLong(maxPkt);
|
|
|
|
buffer.put(data);
|
|
|
|
return buffer.array();
|
|
}
|
|
|
|
|
|
public int getType() {
|
|
return type;
|
|
}
|
|
|
|
|
|
public long getCurPkt() {
|
|
return curPkt;
|
|
}
|
|
|
|
public long getMaxPkt() {
|
|
return maxPkt;
|
|
}
|
|
|
|
|
|
}
|