Mina的ObjectSerialization、TextLine分包分析

Tcp传输数据分包不外乎3个方法:
  • 定长数据包。
  • 带数据长度的包头。
  • 在数据包之间用换行之类的特殊符号分隔。


如果使用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则会在数据末尾添加换行符来分包。

你可能感兴趣的:(serialization)