• <fieldset id="8imwq"><menu id="8imwq"></menu></fieldset>
  • <bdo id="8imwq"><input id="8imwq"></input></bdo>
    最新文章專題視頻專題問答1問答10問答100問答1000問答2000關鍵字專題1關鍵字專題50關鍵字專題500關鍵字專題1500TAG最新視頻文章推薦1 推薦3 推薦5 推薦7 推薦9 推薦11 推薦13 推薦15 推薦17 推薦19 推薦21 推薦23 推薦25 推薦27 推薦29 推薦31 推薦33 推薦35 推薦37視頻文章20視頻文章30視頻文章40視頻文章50視頻文章60 視頻文章70視頻文章80視頻文章90視頻文章100視頻文章120視頻文章140 視頻2關鍵字專題關鍵字專題tag2tag3文章專題文章專題2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章專題3
    問答文章1 問答文章501 問答文章1001 問答文章1501 問答文章2001 問答文章2501 問答文章3001 問答文章3501 問答文章4001 問答文章4501 問答文章5001 問答文章5501 問答文章6001 問答文章6501 問答文章7001 問答文章7501 問答文章8001 問答文章8501 問答文章9001 問答文章9501
    當前位置: 首頁 - 科技 - 知識百科 - 正文

    詳細介紹mysql協議的服務端握手包及對其解析

    來源:懂視網 責編:小采 時間:2020-11-09 09:09:05
    文檔

    詳細介紹mysql協議的服務端握手包及對其解析

    詳細介紹mysql協議的服務端握手包及對其解析:概況mysql客戶端登陸到mysql服務端需要一個交互的過程,這里先看服務端給客戶端發送的初始握手包。如下,client通過socket連接到server指定的端口后,server將往client發送初始握手包。服務端會根據不同的服務版本和不同的配置返回不同的初始化握手包。cli
    推薦度:
    導讀詳細介紹mysql協議的服務端握手包及對其解析:概況mysql客戶端登陸到mysql服務端需要一個交互的過程,這里先看服務端給客戶端發送的初始握手包。如下,client通過socket連接到server指定的端口后,server將往client發送初始握手包。服務端會根據不同的服務版本和不同的配置返回不同的初始化握手包。cli

    概況

    mysql客戶端登陸到mysql服務端需要一個交互的過程,這里先看服務端給客戶端發送的初始握手包。如下,client通過socket連接到server指定的端口后,server將往client發送初始握手包。服務端會根據不同的服務版本和不同的配置返回不同的初始化握手包。

    client 
    server 
    |------connect---- >|
     | |
     |<----handshake-----|
     | |
     | |
     | |

    mysql通信報文結構

    類型名字描述
    int<3>payload長度按照the least significant byte first存儲,3個字節的payload和1個字節的序列號組合成報文頭
    int<1>序列號
    stringpayload報文體,長度即為前面指定的payload長度

    初始握手包

    HandshakeV10協議如下

    1 [0a] protocol version
    string[NUL] server version
    4 connection id
    string[8] auth-plugin-data-part-1
    1 [00] filler
    2 capability flags (lower 2 bytes)
     if more data in the packet:
    1 character set
    2 status flags
    2 capability flags (upper 2 bytes)
     if capabilities & CLIENT_PLUGIN_AUTH {
    1 length of auth-plugin-data
     } else {
    1 [00]
     }
    string[10] reserved (all [00])
     if capabilities & CLIENT_SECURE_CONNECTION {
    string[$len] auth-plugin-data-part-2 ($len=MAX(13, length of auth-plugin-data - 8))
     if capabilities & CLIENT_PLUGIN_AUTH {
     if version >= (5.5.7 and < 5.5.10) or (>= 5.6.0 and < 5.6.2) {
    string[EOF] auth-plugin name
     } elseif version >= 5.5.10 or >= 5.6.2 {
    string[NUL] auth-plugin name
     }
     }

    生成初始握手包

    1. 定義版

    /**
     * 
     * @author seaboat
     * @date 2016-09-25
     * @version 1.0
     * <pre><b>email: </b>849586227@qq.com</pre>
     * <pre><b>blog: </b>http://www.gxlcms.com/;/pre>
     * <p>proxy's version.</p>
     */public interface Versions {
    
     byte PROTOCOL_VERSION = 10; byte[] SERVER_VERSION = "5.6.0-snapshot".getBytes();
    }
    1. 隨機數工具

    /**
     * 
     * @author seaboat
     * @date 2016-09-25
     * @version 1.0
     * <pre><b>email: </b>849586227@qq.com</pre>
     * <pre><b>blog: </b>http://www.gxlcms.com/;/pre>
     * <p>a random util .</p>
     */public class RandomUtil {
     private static final byte[] bytes = { '1', '2', '3', '4', '5', '6', '7', 
     '8', '9', '0', 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', 
     'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', 'z', 'x', 'c', 'v', 
     'b', 'n', 'm', 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', 
     'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', 'Z', 'X', 'C', 'V', 
     'B', 'N', 'M' }; 
     private static final long multiplier = 0x5DEECE66DL; 
     private static final long addend = 0xBL; 
     private static final long mask = (1L << 48) - 1; 
     private static final long integerMask = (1L << 33) - 1; 
     private static final long seedUniquifier = 8682522807148012L; 
     private static long seed; 
     static { 
     long s = seedUniquifier + System.nanoTime();
     s = (s ^ multiplier) & mask;
     seed = s;
     } public static final byte[] randomBytes(int size) { 
     byte[] bb = bytes; 
     byte[] ab = new byte[size]; 
     for (int i = 0; i < size; i++) {
     ab[i] = randomByte(bb);
     } return ab;
     } private static byte randomByte(byte[] b) { 
     int ran = (int) ((next() & integerMask) >>> 16); 
     return b[ran % b.length];
     } private static long next() { 
     long oldSeed = seed; 
     long nextSeed = 0L;
     do {
     nextSeed = (oldSeed * multiplier + addend) & mask;
     } 
     while (oldSeed == nextSeed);
     seed = nextSeed; 
     return nextSeed;
     }
    
    }
    1. mysql包基類

    /**
     * 
     * @author seaboat
     * @date 2016-09-25
     * @version 1.0
     * <pre><b>email: </b>849586227@qq.com</pre>
     * <pre><b>blog: </b>http://www.gxlcms.com/;/pre>
     * <p>MySQLPacket is mysql's basic packet.</p>
     */public abstract class MySQLPacket {
     /**
     * none, this is an internal thread state
     */
     public static final byte COM_SLEEP = 0; /**
     * mysql_close
     */
     public static final byte COM_QUIT = 1; /**
     * mysql_select_db
     */
     public static final byte COM_INIT_DB = 2; /**
     * mysql_real_query
     */
     public static final byte COM_QUERY = 3; /**
     * mysql_list_fields
     */
     public static final byte COM_FIELD_LIST = 4; /**
     * mysql_create_db (deprecated)
     */
     public static final byte COM_CREATE_DB = 5; /**
     * mysql_drop_db (deprecated)
     */
     public static final byte COM_DROP_DB = 6; /**
     * mysql_refresh
     */
     public static final byte COM_REFRESH = 7; /**
     * mysql_shutdown
     */
     public static final byte COM_SHUTDOWN = 8; /**
     * mysql_stat
     */
     public static final byte COM_STATISTICS = 9; /**
     * mysql_list_processes
     */
     public static final byte COM_PROCESS_INFO = 10; /**
     * none, this is an internal thread state
     */
     public static final byte COM_CONNECT = 11; /**
     * mysql_kill
     */
     public static final byte COM_PROCESS_KILL = 12; /**
     * mysql_dump_debug_info
     */
     public static final byte COM_DEBUG = 13; /**
     * mysql_ping
     */
     public static final byte COM_PING = 14; /**
     * none, this is an internal thread state
     */
     public static final byte COM_TIME = 15; /**
     * none, this is an internal thread state
     */
     public static final byte COM_DELAYED_INSERT = 16; /**
     * mysql_change_user
     */
     public static final byte COM_CHANGE_USER = 17; /**
     * used by slave server mysqlbinlog
     */
     public static final byte COM_BINLOG_DUMP = 18; /**
     * used by slave server to get master table
     */
     public static final byte COM_TABLE_DUMP = 19; /**
     * used by slave to log connection to master
     */
     public static final byte COM_CONNECT_OUT = 20; /**
     * used by slave to register to master
     */
     public static final byte COM_REGISTER_SLAVE = 21; /**
     * mysql_stmt_prepare
     */
     public static final byte COM_STMT_PREPARE = 22; /**
     * mysql_stmt_execute
     */
     public static final byte COM_STMT_EXECUTE = 23; /**
     * mysql_stmt_send_long_data
     */
     public static final byte COM_STMT_SEND_LONG_DATA = 24; /**
     * mysql_stmt_close
     */
     public static final byte COM_STMT_CLOSE = 25; /**
     * mysql_stmt_reset
     */
     public static final byte COM_STMT_RESET = 26; /**
     * mysql_set_server_option
     */
     public static final byte COM_SET_OPTION = 27; /**
     * mysql_stmt_fetch
     */
     public static final byte COM_STMT_FETCH = 28; /**
     * mysql packet length
     */
     public int packetLength; /**
     * mysql packet id
     */
     public byte packetId; /**
     * calculate mysql packet length
     */
     public abstract int calcPacketSize(); /**
     * mysql packet info
     */
     protected abstract String getPacketInfo(); @Override
     public String toString() { return new StringBuilder().append(getPacketInfo()).append("{length=")
     .append(packetLength).append(",id=").append(packetId)
     .append('}').toString();
     }
    
    }
    1. 握手包類

    /**
     * 
     * @author seaboat
     * @date 2016-09-25
     * @version 1.0
     * <pre><b>email: </b>849586227@qq.com</pre>
     * <pre><b>blog: </b>http://www.gxlcms.com/;/pre>
     * <p>AuthPacket means mysql initial handshake packet .</p>
     */public class HandshakePacket extends MySQLPacket {
     private static final byte[] FILLER_13 = new byte[] { 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0 }; 
     public byte protocolVersion; 
     public byte[] serverVersion; 
     public long threadId; 
     public byte[] seed; 
     public int serverCapabilities; 
     public byte serverCharsetIndex; 
     public int serverStatus; 
     public byte[] restOfScrambleBuff; 
     public void read(byte[] data) {
     MySQLMessage mm = new MySQLMessage(data);
     packetLength = mm.readUB3();
     packetId = mm.read();
     protocolVersion = mm.read();
     serverVersion = mm.readBytesWithNull();
     threadId = mm.readUB4();
     seed = mm.readBytesWithNull();
     serverCapabilities = mm.readUB2();
     serverCharsetIndex = mm.read();
     serverStatus = mm.readUB2();
     mm.move(13);
     restOfScrambleBuff = mm.readBytesWithNull();
     } @Override
     public int calcPacketSize() { int size = 1;
     size += serverVersion.length;// n
     size += 5;// 1+4
     size += seed.length;// 8
     size += 19;// 1+2+1+2+13
     size += restOfScrambleBuff.length;// 12
     size += 1;// 1
     return size;
     } public void write(ByteBuffer buffer) {
     BufferUtil.writeUB3(buffer, calcPacketSize());
     buffer.put(packetId);
     buffer.put(protocolVersion);
     BufferUtil.writeWithNull(buffer, serverVersion);
     BufferUtil.writeUB4(buffer, threadId);
     BufferUtil.writeWithNull(buffer, seed);
     BufferUtil.writeUB2(buffer, serverCapabilities);
     buffer.put(serverCharsetIndex);
     BufferUtil.writeUB2(buffer, serverStatus);
     buffer.put(FILLER_13);
     BufferUtil.writeWithNull(buffer, restOfScrambleBuff);
     } @Override
     protected String getPacketInfo() { 
     return "MySQL Handshake Packet";
     }
    
    }
    1. 服務端能力類

    /**
     * 
     * @author seaboat
     * @date 2016-09-25
     * @version 1.0
     * <pre><b>email: </b>849586227@qq.com</pre>
     * <pre><b>blog: </b>http://www.gxlcms.com/;/pre>
     * <p>server capabilities .</p>
     */public interface Capabilities {
    
     // new more secure passwords
     int CLIENT_LONG_PASSWORD = 1; // Found instead of affected rows
     int CLIENT_FOUND_ROWS = 2; // Get all column flags
     int CLIENT_LONG_FLAG = 4; // One can specify db on connect
     int CLIENT_CONNECT_WITH_DB = 8; // Don't allow database.table.column
     int CLIENT_NO_SCHEMA = 16; // Can use compression protocol
     int CLIENT_COMPRESS = 32; // Odbc client
     int CLIENT_ODBC = 64; // Can use LOAD DATA LOCAL
     int CLIENT_LOCAL_FILES = 128; // Ignore spaces before '('
     int CLIENT_IGNORE_SPACE = 256; // New 4.1 protocol This is an interactive client
     int CLIENT_PROTOCOL_41 = 512; // This is an interactive client
     int CLIENT_INTERACTIVE = 1024; // Switch to SSL after handshake
     int CLIENT_SSL = 2048; // IGNORE sigpipes
     int CLIENT_IGNORE_SIGPIPE = 4096; // Client knows about transactions
     int CLIENT_TRANSACTIONS = 8192; // Old flag for 4.1 protocol
     int CLIENT_RESERVED = 16384; // New 4.1 authentication
     int CLIENT_SECURE_CONNECTION = 32768; // Enable/disable multi-stmt support
     int CLIENT_MULTI_STATEMENTS = 65536; // Enable/disable multi-results
     int CLIENT_MULTI_RESULTS = 131072;
    
    }
    1. 測試類

    /**
     * 
     * @author seaboat
     * @date 2016-09-25
     * @version 1.0
     * <pre><b>email: </b>849586227@qq.com</pre>
     * <pre><b>blog: </b>http://www.gxlcms.com/;/pre>
     * <p>test handshake packet.</p>
     */public class HandshakePacketTest {
     private final static byte[] hex = "0123456789ABCDEF".getBytes(); @Test
     public void produce() { 
     byte[] rand1 = RandomUtil.randomBytes(8); 
     byte[] rand2 = RandomUtil.randomBytes(12); 
     byte[] seed = new byte[rand1.length + rand2.length];
     System.arraycopy(rand1, 0, seed, 0, rand1.length);
     System.arraycopy(rand2, 0, seed, rand1.length, rand2.length);
     HandshakePacket hs = new HandshakePacket();
     hs.packetId = 0;
     hs.protocolVersion = Versions.PROTOCOL_VERSION;
     hs.serverVersion = Versions.SERVER_VERSION;
     hs.threadId = 1000;
     hs.seed = rand1;
     hs.serverCapabilities = getServerCapabilities();
     hs.serverCharsetIndex = (byte) (CharsetUtil.getIndex("utf8") & 0xff);
     hs.serverStatus = 2;
     hs.restOfScrambleBuff = rand2;
    
     ByteBuffer buffer = ByteBuffer.allocate(256);
     hs.write(buffer);
     buffer.flip(); 
     byte[] bytes = new byte[buffer.remaining()];
     buffer.get(bytes, 0, bytes.length);
     String result = Bytes2HexString(bytes);
     assertTrue(Integer.valueOf(result.substring(0,2),16)==result.length()/2-4);
     } 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();
     } protected int getServerCapabilities() { 
     int flag = 0;
     flag |= Capabilities.CLIENT_LONG_PASSWORD;
     flag |= Capabilities.CLIENT_FOUND_ROWS;
     flag |= Capabilities.CLIENT_LONG_FLAG;
     flag |= Capabilities.CLIENT_CONNECT_WITH_DB;
     flag |= Capabilities.CLIENT_ODBC;
     flag |= Capabilities.CLIENT_IGNORE_SPACE;
     flag |= Capabilities.CLIENT_PROTOCOL_41;
     flag |= Capabilities.CLIENT_INTERACTIVE;
     flag |= Capabilities.CLIENT_IGNORE_SIGPIPE;
     flag |= Capabilities.CLIENT_TRANSACTIONS;
     flag |= Capabilities.CLIENT_SECURE_CONNECTION; 
     return flag;
     }
    
    }

    聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

    文檔

    詳細介紹mysql協議的服務端握手包及對其解析

    詳細介紹mysql協議的服務端握手包及對其解析:概況mysql客戶端登陸到mysql服務端需要一個交互的過程,這里先看服務端給客戶端發送的初始握手包。如下,client通過socket連接到server指定的端口后,server將往client發送初始握手包。服務端會根據不同的服務版本和不同的配置返回不同的初始化握手包。cli
    推薦度:
    標簽: 握手 解析 mysql
    • 熱門焦點

    最新推薦

    猜你喜歡

    熱門推薦

    專題
    Top
    主站蜘蛛池模板: 免费精品久久久久久中文字幕 | 国产精品三级在线| 99re66在线观看精品免费| 亚洲精品中文字幕乱码三区| 丁香色婷婷国产精品视频| 久久国产精品99国产精| 乱人伦人妻精品一区二区| 亚洲色图国产精品| 成人久久精品一区二区三区| 日韩欧精品无码视频无删节| 青青青青久久精品国产h久久精品五福影院1421| 国内精品久久九九国产精品| 日韩精品视频一区二区三区| 无码精品久久一区二区三区| 国产精品亚洲欧美大片在线看| 久久se精品一区精品二区| 国产成人久久精品一区二区三区| 亚洲?V乱码久久精品蜜桃| 久久e热在这里只有国产中文精品99| 亚洲日本精品一区二区| 午夜精品在线观看| 精品成人免费自拍视频| 国产精品成人观看视频免费| 精品国产福利一区二区| 国产精品极品| 日本精品卡一卡2卡3卡四卡| 久久久无码精品亚洲日韩按摩 | 一本久久精品一区二区| 久久精品国产99久久香蕉| 91人妻人人澡人人爽人人精品| 国产成人精品免费午夜app | 亚洲?V无码乱码国产精品| 久久亚洲AV永久无码精品| 国产精品原创巨作?v网站| 国产精品黄页免费高清在线观看| 国产A级毛片久久久精品毛片| 91午夜精品亚洲一区二区三区| 久久精品国产亚洲综合色| 久久久精品午夜免费不卡| 热久久这里只有精品| 办公室久久精品|