mysql 协议的几种包及解析
程序员文章站
2022-04-21 20:17:34
...
mysql通信报文结构
类型 | 名字 | 描述 |
---|---|---|
int<3> | payload长度 | 按照the least significant byte first存储,3个字节的payload和1个字节的序列号组合成报文头 |
int<1> | 序列号 | |
string | payload | 报文体,长度即为前面指定的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"; } }
推荐阅读
-
java 下执行mysql 批量插入的几种方法及用时
-
mysql 协议的ping命令包及解析详解及实例
-
mysql 协议的ping命令包及解析详解及实例
-
Windows 64 位 mysql 5.7以上版本包解压中没有data目录和my-default.ini及服务无法启动的快速解决办法(问题小结)
-
mysql 协议的ping命令包及解析详解及实例
-
java 下执行mysql 批量插入的几种方法及用时
-
Windows 64 位 mysql 5.7以上版本包解压中没有data目录和my-default.ini及服务无法启动的快速解决办法(问题小结)
-
MySQL的几种安装方式及配置问题小结
-
通过rpm包安装、配置及卸载mysql的详细过程
-
mysql 8.0.18 压缩包安装及忘记密码重置所遇到的坑