Mysql通讯协议分析( 三 )

包的总长度是62,减去int<3>+int<1>4字节=58字节,对应的十六进制就是3a;int<3>十六进制为3a00 00表示包内容长度;int<1>十六进制为01表示sequence_id;726f 6f74 00是用户名解码后是root;后面是加密后的密码类型是LengthEncodedString,14对应的十进制是20,后面20个字节就是加密后的密码;可选的数据库名称不存在 。
2.4客户端请求报文
int<1>:执行的命令,比如切换数据库string<var>:命令相应的参数命令列表:
0x00 COM_SLEEP (内部线程状态)0x01 COM_QUIT 关闭连接0x02 COM_INIT_DB 切换数据库0x03 COM_QUERY SQL查询请求0x04 COM_FIELD_LIST 获取数据表字段信息0x05 COM_CREATE_DB 创建数据库0x06 COM_DROP_DB 删除数据库0x07 COM_REFRESH 清除缓存0x08 COM_SHUTDOWN 停止服务器0x09 COM_STATISTICS 获取服务器统计信息0x0A COM_PROCESS_INFO 获取当前连接的列表0x0B COM_CONNECT (内部线程状态)0x0C COM_PROCESS_KILL 中断某个连接0x0D COM_DEBUG 保存服务器调试信息0x0E COM_PING 测试连通性0x0F COM_TIME (内部线程状态)0x10 COM_DELAYED_INSERT (内部线程状态)0x11 COM_CHANGE_USER 重新登陆(不断连接)0x12 COM_BINLOG_DUMP 获取二进制日志信息0x13 COM_TABLE_DUMP 获取数据表结构信息0x14 COM_CONNECT_OUT (内部线程状态)0x15 COM_REGISTER_SLAVE 从服务器向主服务器进行注册0x16 COM_STMT_PREPARE 预处理SQL语句0x17 COM_STMT_EXECUTE 执行预处理语句0x18 COM_STMT_SEND_LONG_DATA 发送BLOB类型的数据0x19 COM_STMT_CLOSE 销毁预处理语句0x1A COM_STMT_RESET 清除预处理语句参数缓存0x1B COM_SET_OPTION 设置语句选项0x1C COM_STMT_FETCH 获取预处理语句的执行结果比如:use test;使用tcpdump进行监听,输出十六进制日志如下:
22:04:29.379165 IP 153.3.251.202.33826 > root.mysql: Flags [P.], seq 122:131, ack 222, win 64019, length 9 0x0000: 4500 0031 3f19 4000 7006 6175 9903 fbca E..1?.@.p.au.... 0x0010: 43da 9190 8422 0cea 42e2 524b 7e18 25c1 C...."..B.RK~.%. 0x0020: 5018 fa13 a07b 0000 0500 0000 0274 6573 P....{.......tes 0x0030: 74 t包的总长度是9,减去int<3>+int<1>4字节=5字节,对应的十六进制就是05;int<3>十六进制为0500 00表示包内容长度;int<1>十六进制为00表示sequence_id;02对应COM_INIT_DB,后面是test的二进制编码;
2.5服务器响应报文
对于客户端发送给服务器的大多数命令,服务器返回其中一个响应的数据包:OK_Packet,ERR_Packet和EOF_Packet,Result Set;
2.5.1OK_Packet
表示成功完成一个命令,具体格式如下:
int<1>:0x00或0xFEOK包头int<lenenc>:受影响行数int<lenenc>:最后插入的索引IDint<2>:服务器状态int<2>:告警计数 注:MySQL 4.1 及之后的版本才有string<lenenc>:服务器消息(可选)use test;服务器返回的包,使用tcpdump进行监听,输出十六进制日志如下:
22:04:29.379308 IP root.mysql > 153.3.251.202.33826: Flags [P.], seq 222:233, ack 131, win 14600, length 11 0x0000: 4508 0033 4a0a 4000 4006 867a 43da 9190 E..3J.@.@..zC... 0x0010: 9903 fbca 0cea 8422 7e18 25c1 42e2 5254 ......."~.%.B.RT 0x0020: 5018 3908 3b61 0000 0700 0001 0000 0002 P.9.;a.......... 0x0030: 0000 00 包的总长度是11,减去int<3>+int<1>4字节=7字节,对应的十六进制就是07;int<3>十六进制为0700 00表示包内容长度;int<1>十六进制为01表示sequence_id;00表示包头;00表示受影响行数;00表示最后插入的索引ID;0200表示服务器状态;
2.5.2ERR_Packet
表示发生了错误,具体格式如下:
int<1>:0xFF ERR包头int<2>:错误码string[1]:Sql状态标识 注:MySQL 4.1 及之后的版本才有string[5]:Sql状态 注:MySQL 4.1 及之后的版本才有string<EOF>:错误消息2.5.3EOF_Packet
以标记查询执行结果的结束:
int<1>:EOF值(0xFE)int<2>:告警计数 注:MySQL 4.1 及之后的版本才有int<2>:状态标志位 注:MySQL 4.1 及之后的版本才有2.5.4Result Set
当客户端发送查询请求后,在没有错误的情况下,服务器会返回结果集(Result Set)给客户端,一共有5个部分:
Result Set Header 返回数据的列数量Field 返回数据的列信息(多个)EOF 列结束Row Data 行数据(多个)EOF 数据结束2.5.4.1Result Set Header
Length-Encoded Integer Field结构的数量Length-Encoded Integer 额外信息2.5.4.2Field
LengthEncodedString 目录名称LengthEncodedString 数据库名称LengthEncodedString 数据表名称LengthEncodedString 数据表原始名称LengthEncodedString 列(字段)名称LengthEncodedString 列(字段)原始名称int<1> 填充值int<2> 字符编码int<4> 列(字段)长度int<1> 列(字段)类型int<2> 列(字段)标志int<1> 整型值精度int<2> 填充值(0x00)LengthEncodedString 默认值


推荐阅读