Exemplo n.º 1
0
        /// <summary>
        /// Handles the asynchronous connect event.
        /// </summary>
        /// <param name="iEvent"></param>
        private void ProcessConnect(SocketAsyncEventArgs iEvent)
        {
            if (iEvent.SocketError == SocketError.Success)
            {                   // notify connected event subscribers
                ConnectedEvent(this, new EventArgs());
                // Depending on the type of protocol, the initial size of the buffer
                // and the buffer object itself will vary.
                // For APP messages, it is important that we identify the length of the expected message first
                // For HTTP messages, the length is stored in the Content-Length parameter
                // For XML messages, the end of the message is identified by a null or SOH character

                // create read buffers
                _RspBfr  = new byte[BUFFER_SIZE];
                _DataBfr = new byte[BUFFER_SIZE];
                Int32  cReadLength = BUFFER_SIZE;
                byte[] aReadBuffer = _DataBfr;

                if (_ProtocolType == AisProtocolType.App)
                {                       // use response read buffer
                    aReadBuffer = _RspBfr;
                    // read the length field first
                    cReadLength = LENGTH_SIZE;
                    // set APP read state to reading response length
                    _AppReadState = AppReadState.ReadingResponseLength;
                }
                _AsyncReadEventArgs = new SocketAsyncEventArgs();
                // assign buffer but read only the length field
                _AsyncReadEventArgs.SetBuffer(aReadBuffer, 0, cReadLength);
                _AsyncReadEventArgs.Completed += new EventHandler <SocketAsyncEventArgs>(ReceiveComplete);

                try
                {                       // asynchronous receive
                    if (!_RemoteSocket.ReceiveAsync(_AsyncReadEventArgs))
                    {                   // if synchronous
                        ProcessReceive(_AsyncReadEventArgs);
                    }
                }
                catch (SocketException aEx)
                { Debug.WriteLine(aEx.Message);

                  // if socket is connected
                  if (_RemoteSocket.Connected)
                  {                             // disconnect from server
                      _RemoteSocket.Close();
                  }
                  // notify disconnected event subscribers
                  DisconnectedEvent(this, new EventArgs());

                  // throw away our socket object
                  _RemoteSocket = null; }
            }
            else
            {                   // create socket error event object
                SocketErrorEventArgs aSocketErrorEventArgs = new SocketErrorEventArgs();
                aSocketErrorEventArgs.Status = (int)iEvent.SocketError;
                aSocketErrorEventArgs.Error  = "Connect failed";

                // notify socket error event subscribers
                SocketErrorEvent(this, aSocketErrorEventArgs);
                //MessageBox.Show("Connect failed");

                // delete socket
                _RemoteSocket = null;
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// Handles the HTTP response.
        /// </summary>
        /// <param name="iEvent">Socket event arguments object.</param>
        private void ProcessHttp(SocketAsyncEventArgs iEvent)
        {
            // resize response buffer if not enough
            if ((_RspLength + iEvent.BytesTransferred) < _RspBfr.Length)
            {
                Array.Resize(ref _RspBfr, _RspLength + iEvent.BytesTransferred);
            }
            // append new data to response buffer
            Array.Copy(iEvent.Buffer, 0, _RspBfr, _RspLength, iEvent.BytesTransferred);

            // update new response length
            _RspLength += iEvent.BytesTransferred;
            Int32  aBeg       = 0;
            Int32  aB         = 0;
            Int32  aEnd       = _RspLength;
            String aTemp      = String.Empty;
            Int32  aMsgLength = 0;

            byte[] aCookie = null;
            bool   aClear  = true;

            // process response buffer loop
            while (aBeg < aEnd)
            {                   // skip whitespaces
                while ((Char.IsWhiteSpace((char)_RspBfr[aBeg])) && (aBeg < aEnd))
                {
                    aBeg++;
                }
                // buffer overflow protection
                if (aBeg == aEnd)
                {
                    aClear = false;
                    break;                     // not enough bytes
                }
                // make sure we can read the protocol header
                if (aBeg + HTTP_HDR.Length > aEnd)
                {
                    aClear = false;
                    break;                     // not enough bytes
                }
                // read the protocol header
                aTemp = System.Text.Encoding.ASCII.GetString(_RspBfr, aBeg, HTTP_HDR.Length);
                if (aTemp != HTTP_HDR)
                {                       // EMIT PROTOCOL ERROR
                    SocketErrorEventArgs aSocketError = new SocketErrorEventArgs();
                    aSocketError.Error = "Unknown Procotol";
                    SocketErrorEvent(this, aSocketError);
                    break;
                }
                aB = aBeg;
                // extract Set-Cookie and Content-Length loop
                do
                {                       // scan past next newline
                    while (aB < aEnd && ((char)_RspBfr[aB++]) != '\n')
                    {
                        ;
                    }

                    if (aB + SET_COOKIE.Length < aEnd &&
                        _RspBfr[aB] == 'S' &&
                        _RspBfr[aB + 1] == 'e' &&
                        _RspBfr[aB + 2] == 't' &&
                        _RspBfr[aB + 3] == '-' &&
                        _RspBfr[aB + 4] == 'C' &&
                        _RspBfr[aB + 5] == 'o' &&
                        _RspBfr[aB + 6] == 'o' &&
                        _RspBfr[aB + 7] == 'k' &&
                        _RspBfr[aB + 8] == 'i' &&
                        _RspBfr[aB + 9] == 'e')
                    {                           // scan past the colon (:)
                        while ((aB < aEnd) && (_RspBfr[aB++] != ':'))
                        {
                            ;
                        }

                        if (aB < aEnd)
                        {
                            Int32 aEol = 0;
                            if (_RspBfr[aB] == ' ')
                            {
                                aB++;
                            }

                            for (aEol = aB; (aEol < aEnd) && (_RspBfr[aEol] != '\r') &&
                                 (_RspBfr[aEol] != '\n'); aEol++)
                            {
                                ;
                            }

                            aCookie = new byte[aEol - aB];
                            Array.Copy(_RspBfr, aB, aCookie, 0, aEol - aB);
                        }
                    }
                    else if (aB + CONTENT_LENGTH.Length < aEnd &&
                             _RspBfr[aB] == 'C' &&
                             _RspBfr[aB + 1] == 'o' &&
                             _RspBfr[aB + 2] == 'n' &&
                             _RspBfr[aB + 3] == 't' &&
                             _RspBfr[aB + 4] == 'e' &&
                             _RspBfr[aB + 5] == 'n' &&
                             _RspBfr[aB + 6] == 't' &&
                             _RspBfr[aB + 7] == '-' &&
                             _RspBfr[aB + 8] == 'L' &&
                             _RspBfr[aB + 9] == 'e' &&
                             _RspBfr[aB + 10] == 'g' &&
                             _RspBfr[aB + 11] == 'n' &&
                             _RspBfr[aB + 12] == 't' &&
                             _RspBfr[aB + 13] == 'h')
                    {
                        while ((aB < aEnd) && _RspBfr[aB] < '0' || _RspBfr[aB] > '9')
                        {
                            aB++;
                        }

                        // get the content-length
                        if (aB < aEnd)
                        {
                            Int32 aEol = 0;
                            for (aEol = aB; (aEol < aEnd) && (_RspBfr[aEol] != '\r') &&
                                 (_RspBfr[aEol] != '\n'); aEol++)
                            {
                                ;
                            }
                            aTemp = Encoding.ASCII.GetString(_RspBfr, aB, (aEol - aB));
                            try
                            { aMsgLength = Int32.Parse(aTemp); }
                            catch (FormatException)
                            { Debug.WriteLine("Invalid Content-Length value."); }
                        }
                    }
                    else if (_RspBfr[aB] == '\r')
                    {
                        aB++;
                    }
                }                 // extract Set-Cookie and Content-Length loop
                while (aB < aEnd && (_RspBfr[aB++]) != '\n');

                // partial. save the partial request.
                // aBeg = Beginning of this message
                // aB = Beginning of the body of request
                if (aB + aMsgLength > aEnd)
                {                       // if aBeg has been moved past the beginning of the buffer
                                        // just keep the partial
                    if (aBeg > 0)
                    {                   // create new buffer
                        byte[] aNewBfr = new byte[aEnd - aBeg];
                        Array.Copy(_RspBfr, aBeg, aNewBfr, 0, aNewBfr.Length);
                        _RspBfr = aNewBfr;
                    }
                    aBeg = aB + aMsgLength;
                    // DO NOT CLEAR BUFFER
                    aClear = false;
                    // quit the main loop
                    break;
                }
                else
                {
                    ResponseEventArgs aHtmlResponse = new ResponseEventArgs();
                    aHtmlResponse.ResponseBuffer = new byte[aMsgLength];
                    aHtmlResponse.CookieBuffer   = aCookie;
                    Array.Copy(_RspBfr, aB, aHtmlResponse.ResponseBuffer, 0, aMsgLength);

                    // emit response signal
                    ResponseEvent(this, aHtmlResponse);

                    // move aBeg to end of body
                    aBeg += aMsgLength;
                }
            }
            if (aClear)
            {
                _RspLength = 0;
            }
            // call asynchronous read again
            _RemoteSocket.ReceiveAsync(iEvent);
        }         // end of process response buffer loop
Exemplo n.º 3
0
        /// <summary>
        /// Handles the XML response.
        /// </summary>
        /// <param name="iEvent">Socket event arguments object.</param>
        private void ProcessXml(SocketAsyncEventArgs iEvent)
        {
            // resize response buffer if not enough
            if ((_RspLength + iEvent.BytesTransferred) < _RspBfr.Length)
            {
                Array.Resize(ref _RspBfr, _RspLength + iEvent.BytesTransferred);
            }
            // append new data to response buffer
            Array.Copy(iEvent.Buffer, 0, _RspBfr, _RspLength, iEvent.BytesTransferred);

            // update new response length
            _RspLength += iEvent.BytesTransferred;
            Int32  aBeg   = 0;
            Int32  aB     = 0;
            Int32  aEnd   = _RspLength;
            String aTemp  = String.Empty;
            bool   aClear = true;

            // process response buffer loop
            while (aBeg < aEnd)
            {                   // skip whitespaces
                while ((Char.IsWhiteSpace((char)_RspBfr[aBeg])) && (aBeg < aEnd))
                {
                    aBeg++;
                }
                // buffer overflow protection
                if (aBeg == aEnd)
                {
                    aClear = false;
                    break;                     // not enough bytes
                }
                // make sure we can read the protocol header
                if (aBeg + XML_HDR.Length > aEnd)
                {
                    aClear = false;
                    break;                     // not enough bytes
                }
                // read the protocol header
                aTemp = System.Text.Encoding.ASCII.GetString(_RspBfr, aBeg, XML_HDR.Length);
                if (aTemp != XML_HDR)
                {                       // EMIT PROTOCOL ERROR
                    SocketErrorEventArgs aSocketError = new SocketErrorEventArgs();
                    aSocketError.Error = "Unknown Protocol";
                    SocketErrorEvent(this, aSocketError);
                    break;
                }
                for (aB = aBeg; aB < aEnd && _RspBfr[aB] > MSG_TERM; aB++)
                {
                    ;
                }

                //  if read past the last character
                if (aB == aEnd)
                {                       // DO NOT CLEAR BUFFER
                    aClear = false;
                    break;
                }
                // partial. save partial request.
                // aBeg - Beginning of next response
                // aB - end of this response
                if (_RspBfr[aB] > MSG_TERM)
                {                       // if aBeg has been moved past the beginning of the buffer
                    if (aBeg > 0)
                    {
                        byte[] aNewBuffer = new byte[aEnd - aBeg];
                        Array.Copy(_RspBfr, aBeg, aNewBuffer, 0, aNewBuffer.Length);
                        _RspBfr = aNewBuffer;
                    }
                    // DO NOT CLEAR BUFFER
                    aClear = false;
                    break;
                }

                // NULL terminate the response
                _RspBfr[aB] = (byte)MSG_NULL;
                ResponseEventArgs aResponse = new ResponseEventArgs();
                aResponse.ResponseBuffer = new byte[aB + 1];
                Array.Copy(_RspBfr, aBeg, aResponse.ResponseBuffer, 0, aB + 1);

                // emit response signal
                ResponseEvent(this, aResponse);

                // move aBeg to
                aBeg = aB + 1;
            }
            if (aClear)
            {
                _RspLength = 0;
            }
            // call asynchronous read again
            _RemoteSocket.ReceiveAsync(iEvent);
        }
Exemplo n.º 4
0
        /// <summary>
        /// Opens a persistent connection to the AIS server.
        /// </summary>
        /// <param name="iHostDnsIP">Hostname or IP Address of the server.</param>
        /// <param name="iPort">Server port.</param>
        /// <returns>true if the operation is successful.</returns>
        /// <remarks>After this function is called, the following events can be received:
        /// 1. ConnectedEvent - When connection to the server is successful.
        /// 2. DisconnectedEvent - When connection to the server is closed/disconnected.
        /// 3. SocketErrorEvent - When there's an error in one of the socket operations.
        /// 4. ResponseEvent - When there's data received from the server.
        /// </remarks>
        public bool OpenConnection(ref String iHostDnsIP, UInt16 iPort)
        {
            bool aRet = false;

            // check parameters and make sure no there's no existing socket connection
            if (iHostDnsIP.Length > 0 && iPort > 0 && _RemoteSocket == null)
            {
                try
                { IPAddress aIPAdd = null;
                  if (!IPAddress.TryParse(iHostDnsIP, out aIPAdd))
                  {                         // resolve host IP
                      IPHostEntry aIPHost = Dns.GetHostEntry(iHostDnsIP);
                      aIPAdd = aIPHost.AddressList[0];
                  }
                  // create end point object
                  IPEndPoint aEndPt = new IPEndPoint(aIPAdd, iPort);

                  // create our socket object
                  _RemoteSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

                  /*
                   * // establish connection with the server
                   * _RemoteSocket.Connect(aEndPt);
                   * // notify connected event subscribers
                   * ConnectedEvent(this, new EventArgs());
                   *
                   * // Depending on the type of protocol, the initial size of the buffer
                   * // and the buffer object itself will vary.
                   * // For APP messages, it is important that we identify the length of the expected message first
                   * // For HTTP messages, the length is stored in the Content-Length parameter
                   * // For XML messages, the end of the message is identified by a null or SOH character
                   * // create read buffers
                   * _RspBfr = new byte[BUFFER_SIZE];
                   * _DataBfr = new byte[BUFFER_SIZE];
                   * Int32 cReadLength = BUFFER_SIZE;
                   * byte[] aReadBuffer = _DataBfr;
                   * if (_ProtocolType == AisProtocolType.App)
                   * {	// use response read buffer
                   *      aReadBuffer = _RspBfr;
                   *      // read the length field first
                   *      cReadLength = LENGTH_SIZE;
                   *      // set APP read state to reading response length
                   *      _AppReadState = AppReadState.ReadingResponseLength;
                   * }
                   * _AsyncReadEventArgs = new SocketAsyncEventArgs();
                   * // assign buffer but read only the length field
                   * _AsyncReadEventArgs.SetBuffer(aReadBuffer, 0, cReadLength);
                   * _AsyncReadEventArgs.Completed += new EventHandler<SocketAsyncEventArgs>(ReceiveComplete);
                   *
                   * // asynchronous receive
                   * if (!_RemoteSocket.ReceiveAsync(_AsyncReadEventArgs))
                   * {
                   *      // if synchronous
                   *      ProcessReceive(_AsyncReadEventArgs);
                   * }*/
                  _AsyncConnEventArgs = new SocketAsyncEventArgs();
                  _AsyncConnEventArgs.RemoteEndPoint = aEndPt;
                  _AsyncConnEventArgs.Completed     += new EventHandler <SocketAsyncEventArgs>(ConnectComplete);
                  if (!_RemoteSocket.ConnectAsync(_AsyncConnEventArgs))
                  {                             // if synchronous
                      ProcessConnect(_AsyncConnEventArgs);
                  }
                  // return success
                  aRet = true; }
                catch (SocketException aEx)
                { Debug.WriteLine(aEx.Message);

                  // if socket object was created successfully
                  if (_RemoteSocket != null)
                  {                             // if socket is connected
                      if (_RemoteSocket.Connected)
                      {                         // disconnect from server
                          _RemoteSocket.Close();

                          // notify disconnected event subscribers
                          DisconnectedEvent(this, new EventArgs());
                      }
                      // throw away our socket object
                      _RemoteSocket = null;
                  }
                  else
                  {                             // create socket error event object
                      SocketErrorEventArgs aSocketErrorEventArgs = new SocketErrorEventArgs();
                      aSocketErrorEventArgs.Status = aEx.ErrorCode;
                      aSocketErrorEventArgs.Error  = aEx.Message;

                      // notify socket error event subscribers
                      SocketErrorEvent(this, aSocketErrorEventArgs);
                  }
                  // return failure
                  aRet = false; }
            }
            return(aRet);
        }