我不知道原因,但无法发送长度超过20,000字节的对象。我喜欢缓冲区的长度低于剩余的长度。我该如何解决这个问题?使用Grizzly和大使图书馆。发送小值时一切都还可以。
系统输出
我的代码:
private static final int HEADER_SIZE = 12;
@Override
public NextAction handleRead(final FilterChainContext ctx) throws IOException {
final Buffer buffer = ctx.getMessage();
System.out.println(buffer.limit());
final int total = buffer.remaining();
if (total < HEADER_SIZE) {
System.out.println("STOPED1 "+" "+total+" < "+HEADER_SIZE);
return ctx.getStopAction(buffer);
}
buffer.get();
buffer.get();
buffer.get();
buffer.get();
int len = buffer.getInt();
if (total < HEADER_SIZE + len) {
System.out.println("STOPED2 "+" "+total+" < "+(HEADER_SIZE+len));
return ctx.getStopAction(buffer);
}
byte[] pack = new byte[len];
buffer.get(pack);
String name = new String(pack);
int size = buffer.getInt();
final int completeMessageLength = HEADER_SIZE + size + len;
if (total < completeMessageLength) {
System.out.println("STOPED3 "+" "+total+" < "+completeMessageLength);
return ctx.getStopAction(buffer);
}
final Buffer remainder = total > completeMessageLength ? buffer.split(completeMessageLength) : null;
System.out.println("PACKET[IN] Name: " + name + " Size: " + total + " BodySize: " + buffer.remaining());
byte[] body = new byte[size];
buffer.get(body);
Packet packet = null;
try {
packet = getPacket(name);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
if (packet == null) {
return ctx.getInvokeAction(remainder);
}
packet.read(body);
handlePacket(ctx.getConnection(), packet);
return ctx.getInvokeAction(remainder);
}
@Override
public NextAction handleWrite(final FilterChainContext ctx) throws IOException {
Packet packet = ctx.getMessage();
String name = packet.getClass().getName();
byte[] packetBody = name.getBytes();
byte[] body = packet.write();
int bodyLen = body.length;
int packetLen = packetBody.length;
final MemoryManager memoryManager = ctx.getConnection().getTransport().getMemoryManager();
int size = HEADER_SIZE + bodyLen + packetLen;
final Buffer output = memoryManager.allocate(size);
output.allowBufferDispose(true);
output.put((byte) 0);
output.put((byte) 0);
output.put((byte) 0);
output.put((byte) 0);
output.putInt(packetLen);
output.put(packetBody);
output.putInt(bodyLen);
output.put(body);
ctx.setMessage(output.flip());
System.out.println("PACKET[OUT] ID: " + name + " Size: " + size);
return ctx.getInvokeAction();
}
protected static Packet getPacket(String name) throws IllegalAccessException {
try {
Class cl = Class.forName(name);
return (Packet) cl.newInstance();
} catch (ClassNotFoundException | InstantiationException e) {
e.printStackTrace();
}
return null;
}
protected abstract void handlePacket(Connection connection, Packet packet);
答案 0 :(得分:0)
在上面的代码中,当条件为假时,您不会退回buffer
位置:if (total < HEADER_SIZE + len)
或if (total < completeMessageLength)
。我认为您应该mark()
之前的位置bufffer
您从buffer
读取了任何内容,然后,如果reset()
不完整,您应该handleRead()
该位置,以便handleRead()
方法可以正确读取数据标头下次。
在我的猜测中,当发送数据小于20000字节时,发送数据不会被分割成不同的数据包,因此handleRead()
每次都会读取完全字节,但它会被分成几个数据包虽然发送数据很大,但$query .= "Select red, green, blue from colorsDB where signoff is not null";
$db->setQuery($query);
$query = $db->loadObjectList();
可能会读取发送数据的一部分。