canal 源码解析(2)-数据流转篇(2)

一、msyql内部指令操作

1)接收msyql发送过来的报文,先获取头部。

header = PacketManager.readHeader(connector.getChannel(), 4);
public static HeaderPacket readHeader(SocketChannel ch, int len) throws IOException {
    HeaderPacket header = new HeaderPacket();
    header.fromBytes(ch.read(len));
    return header;
}
public void fromBytes(byte[] data) {
    if (data == null || data.length != 4) {
        throw new IllegalArgumentException("invalid header data. It can't be null and the length must be 4 byte.");
    }
    this.packetBodyLength = (data[0] & 0xFF) | ((data[1] & 0xFF) << 8) | ((data[2] & 0xFF) << 16);
    this.setPacketSequenceNumber(data[3]);
}

只取了data的前四个字节


2)根据头部大小判断body长度


  开始获取body

byte[] body = PacketManager.readBytes(connector.getChannel(), header.getPacketBodyLength());
public static byte[] readBytes(SocketChannel ch, int len) throws IOException {
    return ch.read(len);
}
若body长度为7,则从input里获取0-7字节放入data

public byte[] read(int readSize) throws IOException {
    InputStream input = this.input;
    byte[] data = new byte[readSize];
    int remain = readSize;
    if (input == null) {
        throw new SocketException("Socket already closed.");
    }
    while (remain > 0) {
        try {
            int read = input.read(data, readSize - remain, remain);
            if (read > -1) {
                remain -= read;
            } else {
                throw new IOException("EOF encountered.");
            }
        } catch (SocketTimeoutException te) {
            if (Thread.interrupted()) {
                throw new ClosedByInterruptException();
            }
        }
    }
    return data;
}

3)获得data为,根据msyql协议里ok报文的特性(如下,)

4)获得ok后,进行下一步操作



二、msyql 日常指令(dml,ddl)操作:

 1)先初始化一个buff,new buffer(32)和chanel,


接收msyql发送过来的data

public boolean fetch() throws IOException {
    try {
        // Fetching packet header from input.
        if (!fetch0(0, NET_HEADER_SIZE)) {
            logger.warn("Reached end of input stream while fetching header");
            return false;
        }

        // Fetching the first packet(may a multi-packet).
        int netlen = getUint24(PACKET_LEN_OFFSET);//body长度
        int netnum = getUint8(PACKET_SEQ_OFFSET);//
        if (!fetch0(NET_HEADER_SIZE, netlen)) {//获取body
            logger.warn("Reached end of input stream: packet #" + netnum + ", len = " + netlen);
            return false;
        }

        // Detecting error code.
        final int mark = getUint8(
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值