mysql 协议解析源码 c_详细介绍mysql 协议的错误包及解析

git

https://github.com/sea-boat/mysql-protocol

概况

mysql客户端与mysql服务端交互过程中,如果服务端遇到错误需要告知客户端则返回错误包。

mysql通信报文结构类型名字描述int<3>payload长度按照the least significant byte first存储,3个字节的payload和1个字节的序列号组合成报文头

int<1>序列号

stringpayload报文体,长度即为前面指定的payload长度

错误包

PayloadTypeNameDescriptionint<1>header[ff] header of the ERR packet

int<2>error_codeerror-code

if capabilities & CLIENT_PROTOCOL_41 {

string[1]sql_state_markermarker of the SQL State

string[5]sql_stateSQL State

}

stringerror_messagehuman readable error message

更多详情 : http://dev.mysql.com/doc/internals/en/packet-ERR_Packet.html

错误包操作错误包类/**

*

* @author seaboat

* @date 2016-09-25

* @version 1.0

*

email: 849586227@qq.com

*

blog: http://www.php.cn/;/pre>

*

mysql error packet.

*/public class ErrorPacket extends MySQLPacket {

public static final byte header = (byte) 0xff;

private static final byte SQLSTATE_MARKER = (byte) '#';

private static final byte[] DEFAULT_SQLSTATE = "HY000".getBytes();

public int errno;

public byte mark = SQLSTATE_MARKER;

public byte[] sqlState = DEFAULT_SQLSTATE;

public byte[] message;

public void read(byte[] data) {

MySQLMessage mm = new MySQLMessage(data);

packetLength = mm.readUB3();

packetId = mm.read();

mm.read();

errno = mm.readUB2();

if (mm.hasRemaining() && (mm.read(mm.position()) == SQLSTATE_MARKER)) {

mm.read();

sqlState = mm.readBytes(5);

}

message = mm.readBytes();

}

public void write(ByteBuffer buffer) {

int size = calcPacketSize();

BufferUtil.writeUB3(buffer, size);

buffer.put(packetId);

buffer.put(header);

BufferUtil.writeUB2(buffer, errno);

buffer.put(mark);

buffer.put(sqlState);

buffer.put(message);

} @Override

public int calcPacketSize() {

int size = 9;// 1 + 2 + 1 + 5

if (message != null) {

size += message.length;

}

return size;

}

@Override

protected String getPacketInfo() {

return "MySQL Error Packet";

}

}十六进制转换工具/**

*

* @author seaboat

* @date 2016-09-25

* @version 1.0

*

email: 849586227@qq.com

*

blog: http://www.php.cn/;/pre>

*

hex transform util.

*/public class HexUtil {

private final static byte[] hex = "0123456789ABCDEF".getBytes();

public static String Bytes2HexString(byte[] b) {

byte[] buff = new byte[2 * b.length];

for (int i = 0; i < b.length; i++) {

buff[2 * i] = hex[(b[i] >> 4) & 0x0f];

buff[2 * i + 1] = hex[b[i] & 0x0f];

} return new String(buff);

} public static String str2HexStr(String str) {

char[] chars = "0123456789ABCDEF".toCharArray();

StringBuilder sb = new StringBuilder("");

byte[] bs = str.getBytes();

int bit;

for (int i = 0; i < bs.length; i++) {

bit = (bs[i] & 0x0f0) >> 4;

sb.append(chars[bit]);

bit = bs[i] & 0x0f;

sb.append(chars[bit]);

} return sb.toString();

}

}错误包生成测试/**

*

* @author seaboat

* @date 2016-09-25

* @version 1.0

*

email: 849586227@qq.com

*

blog: http://www.php.cn/;/pre>

*

test auth packet.

*/public class ErrorPacketTest {

@Test

public void produce() {

ErrorPacket err = new ErrorPacket();

err.packetId = 1;

err.errno = 32322;

err.message = "sorry".getBytes();

ByteBuffer buffer = ByteBuffer.allocate(256);

err.write(buffer);

buffer.flip(); byte[] bytes = new byte[buffer.remaining()];

buffer.get(bytes, 0, bytes.length);

String result = HexUtil.Bytes2HexString(bytes);

System.out.println(result);

assertTrue(Integer.valueOf(result.substring(0, 2), 16) == result

.length() / 2 - 4);

ErrorPacket err2 = new ErrorPacket();

err2.read(bytes);

assertTrue(err2.errno == 32322);

assertTrue(err2.message.length == "sorry".getBytes().length);

}

}

以上就是详细介绍mysql 协议的错误包及解析的内容,更多相关内容请关注PHP中文网(www.php.cn)!

f68f2add0b68e4f9810432fce46917b7.png

本文原创发布php中文网,转载请注明出处,感谢您的尊重!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值