示例#1
0
        void ParseReceivePacket()
        {
            //TODO: review here, optimized buffer
            _receiveBuffer = new byte[DEFAULT_BUFFER_SIZE];
            var socket  = _conn.socket;
            int receive = socket.Receive(_receiveBuffer);

            if (receive == 0)
            {
                return;
            }

            //---------------------------------------------------
            //TODO: review err handling
            _parser.LoadNewBuffer(_receiveBuffer, receive);
            switch (_receiveBuffer[4])
            {
            case ERROR_CODE:
                LoadError = new ErrPacket();
                LoadError.ParsePacket(_parser);
                break;

            case 0xfe:    //0x00 or 0xfe the OK packet header
            case OK_CODE:
                OkPacket = new OkPacket(_conn.IsProtocol41);
                OkPacket.ParsePacket(_parser);
                break;

            default:
                ParseResultSet();
                break;
            }
        }
示例#2
0
 bool Parse_Ok_Content(MySqlStreamReader reader)
 {
     if (!reader.Ensure(_currentHeader.ContentLength)) //check if length is enough to parse
     {
         return(_needMoreData = true);
     }
     if (this._currentMultResultSet != null)
     {
         //in multiple result set mode ***
         //see https://dev.mysql.com/doc/internals/en/multi-resultset.html
         //
         var okPacket = new OkPacket(_currentHeader, this._isProtocol41);
         okPacket.ParsePacketContent(reader);
         _parseResult  = _currentMultResultSet;
         _parsingState = ResultPacketState.ShouldEnd; //*
         //
         _currentMultResultSet = null;                //reset
     }
     else
     {
         var okPacket = new OkPacket(_currentHeader, this._isProtocol41);
         okPacket.ParsePacketContent(reader);
         _parseResult  = new MySqlOkResult(okPacket);
         _parsingState = ResultPacketState.ShouldEnd; //*
     }
     return(true);
 }
示例#3
0
        public void Connect()
        {
            if (State == ConnectionState.Connected)
            {
                throw new NotSupportedException("already connected");
            }

            var endpoint = new IPEndPoint(IPAddress.Parse(config.host), config.port);

            socket.Connect(endpoint);

            byte[] buffer = new byte[512];
            int    count  = socket.Receive(buffer);

            if (count > 0)
            {
                _writer.Reset();
                _parser.LoadNewBuffer(buffer, count);
                _handshake = new HandshakePacket();
                _handshake.ParsePacket(_parser);
                threadId = _handshake.threadId;

                byte[] token = MakeToken(config.password,
                                         GetScrollbleBuffer(_handshake.scrambleBuff1, _handshake.scrambleBuff2));

                _writer.IncrementPacketNumber();

                //------------------------------------------
                var authPacket = new ClientAuthenticationPacket();
                authPacket.SetValues(config.user, token, config.database, _handshake.protocol41);
                authPacket.WritePacket(_writer);

                byte[] sendBuff    = _writer.ToArray();
                byte[] receiveBuff = new byte[512];
                //-------------------------------------------
                //send data
                int sendNum    = socket.Send(sendBuff);
                int receiveNum = socket.Receive(receiveBuff);

                _parser.LoadNewBuffer(receiveBuff, receiveNum);
                if (receiveBuff[4] == 255)
                {
                    ErrPacket errPacket = new ErrPacket();
                    errPacket.ParsePacket(_parser);
                    return;
                }
                else
                {
                    OkPacket okPacket = new OkPacket(_handshake.protocol41);
                    okPacket.ParsePacket(_parser);
                }
                _writer.Reset();
                GetMaxAllowedPacket();
                _writer.SetMaxAllowedPacket(_maxPacketSize);
            }
        }
示例#4
0
        void RecvPacket_A(Action whenRecv)
        {
            _recvComplete = false;
            bool isFirstRecv = true;

            //before start recv
            _conn.StartReceive(result =>
            {
                if (result == null)
                {
                    throw new NotSupportedException();
                }
                else
                {
                    switch (result.Kind)
                    {
                    default: throw new NotSupportedException();    //unknown

                    case MySqlResultKind.Ok:
                        {
                            OkPacket = (result as MySqlOkResult).okpacket;
                            RecvComplete();
                        }
                        break;

                    case MySqlResultKind.Error:
                        {
                            MySqlErrorResult error = result as MySqlErrorResult;
                            Error = error.errPacket;
                            RecvComplete();
                            if (_errorListener != null)
                            {
                                _errorListener(error);
                            }
                            else
                            {
                                //ERROR
                                throw new MySqlExecException(error);
                            }
                        }
                        break;

                    case MySqlResultKind.PrepareResponse:
                        {
                            //The server will send a OK_Packet if the statement could be reset, a ERR_Packet if not.
                            //on prepare
                            MySqlPrepareResponseResult response = result as MySqlPrepareResponseResult;
                            _prepareContext = new PreparedContext(
                                response.okPacket.statement_id,
                                _sqlStrTemplate,
                                response.tableHeader);
                            RecvComplete();
                        }
                        break;

                    case MySqlResultKind.TableResult:
                        {
                            //support partial table mode
                            //last sub table is not partial table
                            //and must notify reader first***
                            //before call  RecvComplete();

                            //-----------------------------------------
                            MySqlTableResult tableResult = result as MySqlTableResult;
                            //***
                            _recvComplete = !tableResult.HasFollower;
                            //the _tableResultListener may modifid by other state (Close)
                            //if don't lock we need to store it to local var
                            _tableResultListener?.Invoke(tableResult);
                            //-----------------------------------------
                            if (!tableResult.HasFollower)
                            {
                                RecvComplete();
                            }
                        }
                        break;

                    case MySqlResultKind.MultiTableResult:
                        {
                            MySqlMultiTableResult multiTables = result as MySqlMultiTableResult;
                            List <MySqlTableResult> subTables = multiTables.subTables;
                            int j = subTables.Count;
                            for (int i = 0; i < j; ++i)
                            {
                                MySqlTableResult table = subTables[i];
                                if (i < j - 1)
                                {
                                    //not the last one
                                    //(the last one may complete or not complete)
                                    table.HasFollower = true;

                                    //the _tableResultListener may modifid by other state (Close)
                                    //if don't lock we need to store it to local var
                                    _tableResultListener?.Invoke(table);
                                }
                                else
                                {
                                    //this is the last one in the series
                                    //support partial table mode
                                    //last sub table is not partial table
                                    //and must notify reader first***
                                    //before call  RecvComplete();

                                    _recvComplete = !table.HasFollower;

                                    //the _tableResultListener may modifid by other state (Close)
                                    //if don't lock we need to store it to local var
                                    _tableResultListener?.Invoke(table);

                                    if (!table.HasFollower)
                                    {
                                        RecvComplete();
                                    }
                                }
                            }
                        }
                        break;
                    }
                }
                //-----------------
                //exec once
                if (isFirstRecv)
                {
                    isFirstRecv = false;
                    whenRecv();
                    whenRecv = null;
                }
                //-----------------
            });
        }
 public MySqlOkResult(OkPacket okpacket)
 {
     this.okpacket = okpacket;
 }
示例#6
0
        void RecvPacket_A(Action whenRecv)
        {

            _recvComplete = false;
            bool isFirstRecv = true;
            _conn.StartReceive(result =>
            {
                if (result == null)
                {
                    throw new NotSupportedException();
                }
                else
                {
                    switch (result.Kind)
                    {
                        default: throw new NotSupportedException();//unknown
                        case MySqlResultKind.Ok:
                            {
                                MySqlOkResult ok = result as MySqlOkResult;
                                OkPacket = ok.okpacket;

                                RecvComplete();
                            }
                            break;
                        case MySqlResultKind.Error:
                            {
                                MySqlErrorResult error = result as MySqlErrorResult;
                                LoadError = error.errPacket;
                                RecvComplete();
                            }
                            break;
                        case MySqlResultKind.PrepareResponse:
                            {
                                //The server will send a OK_Packet if the statement could be reset, a ERR_Packet if not.
                                //on prepare
                                MySqlPrepareResponseResult response = result as MySqlPrepareResponseResult;
                                _prepareContext = new PreparedContext(
                                    response.okPacket.statement_id,
                                    _sqlStrTemplate,
                                    response.tableHeader);
                                RecvComplete();
                            }
                            break;
                        case MySqlResultKind.TableResult:
                            {
                                //support partial table mode 
                                //last sub table is not partial table  
                                //and must notify reader first***
                                //before call  RecvComplete();

                                //-----------------------------------------  
                                MySqlTableResult tableResult = result as MySqlTableResult;
                                //***
                                _recvComplete = !tableResult.HasFollower;

                                if (_tableResultListener != null)
                                {
                                    //the _tableResultListener may modifid by other state (Close)
                                    //if don't lock we need to store it to local var
                                    _tableResultListener(tableResult);
                                }

                                //----------------------------------------- 
                                if (!tableResult.HasFollower)
                                {
                                    RecvComplete();
                                }
                            }
                            break;
                        case MySqlResultKind.MultiTableResult:
                            {
                                MySqlMultiTableResult multiTables = result as MySqlMultiTableResult;
                                List<MySqlTableResult> subTables = multiTables.subTables;
                                int j = subTables.Count;
                                for (int i = 0; i < j; ++i)
                                {
                                    MySqlTableResult table = subTables[i];
                                    if (i < j - 1)
                                    {
                                        //not the last one
                                        //(the last one may complete or not complete)
                                        table.HasFollower = true;
                                        if (_tableResultListener != null)
                                        {
                                            //the _tableResultListener may modifid by other state (Close)
                                            //if don't lock we need to store it to local var
                                            _tableResultListener(table);
                                        }
                                    }
                                    else
                                    {
                                        //this is the last one in the series
                                        //support partial table mode 
                                        //last sub table is not partial table  
                                        //and must notify reader first***
                                        //before call  RecvComplete();

                                        _recvComplete = !table.HasFollower;
                                        if (_tableResultListener != null)
                                        {
                                            //the _tableResultListener may modifid by other state (Close)
                                            //if don't lock we need to store it to local var
                                            _tableResultListener(table);
                                        }

                                        if (!table.HasFollower)
                                        {
                                            RecvComplete();
                                        }
                                    }
                                }

                            }
                            break;
                    }
                }
                //-----------------
                //exec once
                if (isFirstRecv)
                {
                    isFirstRecv = false;
                    whenRecv();
                    whenRecv = null;
                }
                //-----------------
            });
        }
示例#7
0
        public void ConnectAsync(Action connHandler)
        {
            //1. socket
            socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            _saea.SetBuffer(_sockBuffer, 0, _sockBuffer.Length);

            //2. buffer
            _connSession       = new MySqlConnectionSession(_saea, 1024, 1024);
            _saea.UserToken    = _connSession;
            _saea.AcceptSocket = socket;

            var endPoint = new IPEndPoint(IPAddress.Parse(config.host), config.port);

            //first connect
            socket.Connect(endPoint);
            _connSession.StartReceive(recv =>
            {
                //TODO: review here, don't copy,
                //we should use shared sockBuffer

                byte[] buffer = new byte[512];
                int count     = recv.BytesTransferred;
                recv.CopyTo(0, buffer, 0, recv.BytesTransferred);
                _parser.LoadNewBuffer(buffer, count);
                _handshake = new HandshakePacket();
                _handshake.ParsePacket(_parser);
                this.threadId = _handshake.threadId;

                byte[] token = MakeToken(config.password,
                                         GetScrollbleBuffer(_handshake.scrambleBuff1, _handshake.scrambleBuff2));

                _writer.Reset();
                _writer.IncrementPacketNumber();
                //------------------------------------------
                var authPacket = new ClientAuthenticationPacket();
                authPacket.SetValues(config.user, token, config.database, _handshake.protocol41);
                authPacket.WritePacket(_writer);

                //send
                //do authen
                //handle
                recv._recvAction = () =>
                {
                    byte[] sendBuff    = _writer.ToArray();
                    byte[] receiveBuff = new byte[512];
                    //-------------------------------------------

                    //send data
                    int sendNum    = socket.Send(sendBuff);
                    int receiveNum = socket.Receive(receiveBuff);

                    _parser.LoadNewBuffer(receiveBuff, receiveNum);
                    if (receiveBuff[4] == 255)
                    {
                        ErrPacket errPacket = new ErrPacket();
                        errPacket.ParsePacket(_parser);
                    }
                    else
                    {
                        OkPacket okPacket = new OkPacket(_handshake.protocol41);
                        okPacket.ParsePacket(_parser);
                    }
                    _writer.Reset();
                    GetMaxAllowedPacket();
                    if (_maxPacketSize > 0)
                    {
                        _writer.SetMaxAllowedPacket(_maxPacketSize);
                    }

                    if (connHandler != null)
                    {
                        connHandler();
                    }
                };
                return(EndReceiveState.Complete);
            });
        }
 public MySqlOkResult(OkPacket okpacket)
 {
     this.okpacket = okpacket;
 }
 bool Parse_Ok_Content(MySqlStreamReader reader)
 {
     if (!reader.Ensure(_currentHeader.ContentLength)) //check if length is enough to parse 
     {
         return _needMoreData = true;
     }
     if (this._currentMultResultSet != null)
     {
         //in multiple result set mode ***
         //see https://dev.mysql.com/doc/internals/en/multi-resultset.html
         //
         var okPacket = new OkPacket(_currentHeader, this._isProtocol41);
         okPacket.ParsePacketContent(reader);
         _parseResult = _currentMultResultSet;
         _parsingState = ResultPacketState.ShouldEnd; //*
         //
         _currentMultResultSet = null;//reset 
     }
     else
     {
         var okPacket = new OkPacket(_currentHeader, this._isProtocol41);
         okPacket.ParsePacketContent(reader);
         _parseResult = new MySqlOkResult(okPacket);
         _parsingState = ResultPacketState.ShouldEnd; //*
     }
     return true;
 }