前言
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 Number
和 Affected Rows
之间还有0x00
就是我框出来的00
。所以数据还是有的,只是MySQL Protocol
没有显示而已。
第二个要讲的是自增id。在上面的包中也没有显示,但是在下面具体数据中可以看到Affected Rows
和Server 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。