Mina的ObjectSerialization、TextLine分包分析

版权声明:拓洲网络创始人翁志艺,官网https://www.yiqishare.com https://blog.csdn.net/iteye_7863/article/details/82480273
Tcp传输数据分包不外乎3个方法:
[list]
[*]定长数据包。
[*]带数据长度的包头。
[*]在数据包之间用换行之类的特殊符号分隔。
[/list]

如果使用ObjectSerializationCodecFactory的ProtocolCodecFilter直接传输Java类对象的话,实际上会在要传输的数据前加上4个字节的来表示数据长度。关键代码如下:


public void encode(IoSession session, Object message,
ProtocolEncoderOutput out) throws Exception {
if (!(message instanceof Serializable)) {
throw new NotSerializableException();
}

IoBuffer buf = IoBuffer.allocate(64);
buf.setAutoExpand(true);
buf.putObject(message);//存入IoBuffer中

int objectSize = buf.position() - 4;
if (objectSize > maxObjectSize) {
throw new IllegalArgumentException(
"The encoded object is too big: " + objectSize + " (> "
+ maxObjectSize + ')');
}

buf.flip();
out.write(buf);
}

public IoBuffer putObject(Object o) {
int oldPos = position();
skip(4); // 跳过前4字节
try {
ObjectOutputStream out = new ObjectOutputStream(asOutputStream()) {
@Override
protected void writeClassDescriptor(ObjectStreamClass desc)
throws IOException {
try {
Class<?> clz = Class.forName(desc.getName());
if (!Serializable.class.isAssignableFrom(clz)) { // NON-Serializable class
write(0);
super.writeClassDescriptor(desc);
} else { // Serializable class
write(1);
writeUTF(desc.getName());
}
}
catch (ClassNotFoundException ex) { // Primitive types
write(0);
super.writeClassDescriptor(desc);
}
}
};
out.writeObject(o);
out.flush();
} catch (IOException e) {
throw new BufferDataException(e);
}

// 填充数据长度
int newPos = position();
position(oldPos);
putInt(newPos - oldPos - 4);
position(newPos);
return this;
}


而使用TextLineDecoder、TextLineEncoder则会在数据末尾添加换行符来分包。

[color=white]作者:翁志艺[/color]

猜你喜欢

转载自blog.csdn.net/iteye_7863/article/details/82480273