当前位置:Gxlcms > mysql > mysql协议的几种包及解析

mysql协议的几种包及解析

时间:2021-07-01 10:21:17 帮助过:21人阅读

mysql通信报文结构

类型名字描述
int<3>payload长度按照the least significant byte first存储,3个字节的payload和1个字节的序列号组合成报文头
int<1>序列号
stringpayload报文体,长度即为前面指定的payload长度

ResultsetRow包

Payload

if(NULL){  
0xfb
}else{
  Protocol::LengthEncodedString
}

ResultsetRow包类

public class ResultsetRowPacket extends MySQLPacket {
    private static final byte NULL_MARK = (byte) 251;
    public int columnCount;
    public List<byte[]> columnValues;

    public ResultsetRowPacket() {

    }

    public ResultsetRowPacket(int columnCount) {
        this.columnCount = columnCount;
    }

    @Override
    public void read(byte[] data) {
        MySQLMessage mm = new MySQLMessage(data);
        packetLength = mm.readUB3();
        packetId = mm.read();
        for (int i = 0; i < columnCount; i++) {
            columnValues.add(mm.readBytesWithLength());
        }
    }

    @Override
    public void write(ByteBuffer buffer) {
        BufferUtil.writeUB3(buffer, calcPacketSize());
        buffer.put(packetId);
        for (int i = 0; i < columnCount; i++) {
            byte[] fv = columnValues.get(i);
            if (fv == null) {
                buffer.put(NULL_MARK);
            } else {
                BufferUtil.writeLength(buffer, fv.length);
                buffer.put(fv);
            }
        }
    }

    @Override
    public int calcPacketSize() {
        int size = 0;
        for (int i = 0; i < columnCount; i++) {
            byte[] v = columnValues.get(i);
            size += (v == null || v.length == 0) ? 1 : BufferUtil.getLength(v);
        }
        return size;
    }

    @Override
    protected String getPacketInfo() {
        return "MySQL Resultset Row Packet";
    }

}

ColumnDefinition包

Payload

lenenc_str     catalog
lenenc_str     schema
lenenc_str     table
lenenc_str     org_table
lenenc_str     name
lenenc_str     org_name
lenenc_int     length of fixed-length fields [0c]
2              character set
4              column length
1              type
2              flags
1              decimals
2              filler [00] [00]
  if command was COM_FIELD_LIST {
lenenc_int     length of default-values
string[$len]   default values
  }

ColumnCount包类

public class ColumnDefinitionPacket extends MySQLPacket {
    private static final byte[] DEFAULT_CATALOG = "def".getBytes();
    private static final byte NEXT_LENGTH = 0x0c;
    private static final byte[] FILLER = { 00, 00 };

    public byte[] catalog = DEFAULT_CATALOG;// always "def"
    public byte[] schema;
    public byte[] table;
    public byte[] orgTable;
    public byte[] name;
    public byte[] orgName;
    public byte nextLength = NEXT_LENGTH;// always 0x0c
    public int charsetSet;
    public long length;
    public int type;
    public int flags;
    public byte decimals;
    public byte[] filler = FILLER;
    public byte[] defaultValues;

    public void read(byte[] data) {
        MySQLMessage mm = new MySQLMessage(data);
        this.packetLength = mm.readUB3();
        this.packetId = mm.read();
        this.catalog = mm.readBytesWithLength();
        this.schema = mm.readBytesWithLength();
        this.table = mm.readBytesWithLength();
        this.orgTable = mm.readBytesWithLength();
        this.name = mm.readBytesWithLength();
        this.orgName = mm.readBytesWithLength();
        this.nextLength = mm.read();
        this.charsetSet = mm.readUB2();
        this.length = mm.readUB4();
        this.type = mm.read() & 0xff;
        this.flags = mm.readUB2();
        this.decimals = mm.read();
        this.filler = mm.readBytes(2);
        if (mm.hasRemaining()) {
            this.defaultValues = mm.readBytesWithLength();
        }
    }

    @Override
    public void write(ByteBuffer buffer) {
        int size = calcPacketSize();
        BufferUtil.writeUB3(buffer, size);
        buffer.put(packetId);
        BufferUtil.writeWithLength(buffer, catalog, (byte) 0);
        BufferUtil.writeWithLength(buffer, schema, (byte) 0);
        BufferUtil.writeWithLength(buffer, table, (byte) 0);
        BufferUtil.writeWithLength(buffer, orgTable, (byte) 0);
        BufferUtil.writeWithLength(buffer, name, (byte) 0);
        BufferUtil.writeWithLength(buffer, orgName, (byte) 0);
        buffer.put(NEXT_LENGTH);
        BufferUtil.writeUB2(buffer, charsetSet);
        BufferUtil.writeUB4(buffer, length);
        buffer.put((byte) (type & 0xff));
        BufferUtil.writeUB2(buffer, flags);
        buffer.put(decimals);
        buffer.put(FILLER);
        if (defaultValues != null) {
            //only use for show columns
            BufferUtil.writeWithLength(buffer, defaultValues);
        }
    }

    @Override
    public int calcPacketSize() {
        int size = (catalog == null ? 1 : BufferUtil.getLength(catalog));
        size += (schema == null ? 1 : BufferUtil.getLength(schema));
        size += (table == null ? 1 : BufferUtil.getLength(table));
        size += (orgTable == null ? 1 : BufferUtil.getLength(orgTable));
        size += (name == null ? 1 : BufferUtil.getLength(name));
        size += (orgName == null ? 1 : BufferUtil.getLength(orgName));
        size += 13;
        if (defaultValues != null) {
            size += BufferUtil.getLength(defaultValues);
        }
        return size;
    }

    @Override
    protected String getPacketInfo() {
        return "MySQL Column Definition Packet";
    }

}

ColumnCount包

Payload

Protocol::LengthEncodedInteger

ColumnCount包类

public class ColumnCountPacket extends MySQLPacket {

    public int columnCount;

    public void read(byte[] data) {
        MySQLMessage mm = new MySQLMessage(data);
        this.packetLength = mm.readUB3();
        this.packetId = mm.read();
        this.columnCount = (int) mm.readLength();
    }

    @Override
    public void write(ByteBuffer buffer) {
        int size = calcPacketSize();
        BufferUtil.writeUB3(buffer, size);
        buffer.put(packetId);
        BufferUtil.writeLength(buffer, columnCount);
    }

    @Override
    public int calcPacketSize() {
        int size = BufferUtil.getLength(columnCount);
        return size;
    }

    @Override
    protected String getPacketInfo() {
        return "MySQL Column Count Packet";
    }

}

人气教程排行