实现自己的数据库驱动——MySQL协议OK/Error包解析(五)

前言

OK/Error Packet是由Server端向Client发送的请求回应。所以这篇主要来解析一下这两个Packet,以及解释一下为什么Wireshark抓到的包与网上的格式有所差别。

OK Packet

OK Packet数据格式

普通的OK包会在以下几种情况下产生,由Server发送给相应的接收方:

  • COM_PING: 连接或者测试数据库
  • COM_QUERY: 不需要查询结果集的操作,比如INSERT, UPDATE, or ALTER TABLE
  • COM_REFRESH: 数据刷新
  • COM_REGISTER_SLAVE: 注册从服务器

首先前面的四个字节是包头,其中前三位代表packet数据长度,第四位是包序列号。以下是OK Packet的四字节后的内容。

相对包内容的位置 长度(字节) 名称 描述
0 1 包头标识 0x00 代表这是一个OK 包
1 rows_len 影响行数 相应操作影响的行数,比如一个Update操作的记录是5条,那么这个值就为5
1 + rows_len id_len 自增id 插入一条记录时,如果是自增id的话,返回的id值
1 + rows_len + id_len 2 服务器状态 用于表示服务器状态,比如是否是事务模式或者自动提交模式
3 + rows_len + id_len 2 警告数 上次命令引起的警告数
5 + rows_len + id_len msg_len 额外信息 此次操作的一些额外信息

初看这个格式,你们会发现你们的OK包和上面的数据格式是对不上的。用WireShark来解析一下。

要讲的第一个点就是包头标志。用Wireshark分析的时候,可以看到MySQL Protocol中没有包头标志这个数据的。但是实际上你看具体的16进制数据会发现,Packet NumberAffected Rows之间还有0x00就是我框出来的00。所以数据还是有的,只是MySQL Protocol没有显示而已。

你想输入的替代文字

第二个要讲的是自增id。在上面的包中也没有显示,但是在下面具体数据中可以看到Affected RowsServer status还有一个0x00来存放自增长ID。当我们执行插入语句时就会发现这个字段就可以看到了。

你想输入的替代文字

第三个要说明的是额外信息。在执行更新操作时,就可以看到额外信息了。

你想输入的替代文字

宗上面的分析,OK Packet的格式是能对应上的,只是根据不同SQL请求,字段的数据才会显示出来。

Error Packet

Error Packet数据格式

同样下面是第四字节后具体内容。

相对包内容的位置 长度(字节) 名称 描述
0 1 包头标识 0xFF 代表这是一个Error 包
1 2 错误代码 该错误的相应错误代码
3 1 标识位 SQL执行状态标识位,用’#’进行标识
4 5 执行状态 SQL的具体执行状态
9 msg_len 错误信息 具体的错误信息

Wireshark分析的界面如下,最重要的信息是错误msg。

你想输入的替代文字