87 lines
2.5 KiB
Java
87 lines
2.5 KiB
Java
package org.kne.cloud.network.perf;
|
||
|
||
import java.io.EOFException;
|
||
import java.io.IOException;
|
||
import java.nio.ByteBuffer;
|
||
import java.nio.channels.ReadableByteChannel;
|
||
import java.nio.channels.WritableByteChannel;
|
||
|
||
import org.kne.cloud.network.NetworkPacket;
|
||
import org.kne.cloud.network.klalb.KLALBPacket;
|
||
|
||
public class TESTNPacket extends KLALBPacket {
|
||
|
||
private static final int HEADER_LENGTH = 3;
|
||
|
||
// 核心:一个线程私有的 65535 字节大缓存,生命周期与线程同寿
|
||
private static final ThreadLocal<ByteBuffer> BENCH_BUFFER =
|
||
ThreadLocal.withInitial(() -> ByteBuffer.allocate(65535));
|
||
|
||
// 不再持有 ByteBuffer,只记录长度
|
||
private int payloadLength;
|
||
|
||
@Override
|
||
public long getTotalLength() {
|
||
return HEADER_LENGTH + payloadLength;
|
||
}
|
||
|
||
// 发送端构造
|
||
public TESTNPacket(int limit) {
|
||
super(TESTN, HEADER_LENGTH);
|
||
this.payloadLength = limit;
|
||
}
|
||
|
||
// 接收端构造(从已有的 ByteBuffer 解析)
|
||
public TESTNPacket(ByteBuffer bb) {
|
||
super(bb, HEADER_LENGTH);
|
||
this.payloadLength = klalbHeader.getChar(1);
|
||
}
|
||
|
||
public int getPayloadLength() {
|
||
return payloadLength;
|
||
}
|
||
|
||
@Override
|
||
public void writeToChannel(WritableByteChannel dto) throws IOException {
|
||
// 1. 写入包头(包含 payloadLength)
|
||
klalbHeader.putChar(1, (char) payloadLength);
|
||
super.writeToChannel(dto);
|
||
|
||
// 2. 如果有 payload,借用 ThreadLocal 缓冲区并写出去
|
||
if (payloadLength > 0) {
|
||
ByteBuffer buf = BENCH_BUFFER.get();
|
||
buf.clear();
|
||
buf.limit(payloadLength); // 限制到指定长度
|
||
|
||
// 直接写出,里面的数据是上一次残留的或者全 0,对于烤机无所谓
|
||
dto.write(buf);
|
||
}
|
||
}
|
||
|
||
@Override
|
||
public void readFromChannel(ReadableByteChannel din) throws IOException {
|
||
// 1. 读包头
|
||
super.readFromChannel(din);
|
||
this.payloadLength = klalbHeader.getChar(1);
|
||
|
||
// 2. 如果有 payload,借用缓冲区接收数据
|
||
if (payloadLength > 0) {
|
||
ByteBuffer buf = BENCH_BUFFER.get();
|
||
buf.clear();
|
||
buf.limit(payloadLength);
|
||
|
||
// 循环读满(使用你现有的 KNEChannels 工具或手动循环)
|
||
while (buf.hasRemaining()) {
|
||
if (din.read(buf) == -1) {
|
||
throw new EOFException("连接提前断开,未能读满 TESTN 载荷");
|
||
}
|
||
}
|
||
// 数据读完直接丢弃,缓冲区不保存,下一次 clear() 时会自动覆盖
|
||
}
|
||
}
|
||
|
||
@Override
|
||
public String toString() {
|
||
return "TESTN[" + payloadLength + "]";
|
||
}
|
||
} |