Example #1
0
        /// <summary>
        /// Send the given data to the server using the established connection
        /// </summary>
        /// <param name="data">The data to send to the server</param>
        /// <param name="numAttempts">The number of times a send has already been tried</param>
        /// <returns>True if the send succeeds.</returns>
        private async Task <bool> Send(string data, int numAttempts)
        {
            PrintLine();

            // initialize some values
            bool        timerPopped = false;
            Task <bool> awaitable   = null;

            System.Diagnostics.Debug.WriteLine(String.Format(">> {0} [{1}]", data, numAttempts));

            // check the number of attempts
            if (numAttempts >= MAX_SEND_ATTEMPS)
            {
                var e = new TimeoutException("Too many attempts to send \"" +
                                             data + "\" to remote server");
                FatalException(this, new FatalEventArgs(
                                   ExceptionType.SEND_FAILED, e));
                throw e;
            }

            // We are re-using the _socket object initialized in the Connect method
            if (_socket == null || _dataWriter == null)
            {
                var e = new NullReferenceException(
                    "Socket is null while attempting to send message \"" + data + "\"");
                NonFatalException(this, new NonFatalEventArgs(
                                      ExceptionType.SEND_RECEIVE_NO_SOCKET, e));
                throw e;
            }

            // Write the string.
            // Writing data to the writer will just store data in memory.
            if (numAttempts == 0)
            {
                _dataWriter.WriteUInt32(Convert.ToUInt32(data.Length));
                _dataWriter.WriteString(data);
            }

            // attempt to write the data
            try
            {
                // Write the locally buffered data to the network.
                var timer = new AwaitTimer(3000);
                timerPopped = !timer.timeTask(_dataWriter.StoreAsync());
            }
            catch (Exception e)
            {
                if (e.Message == CONNECTION_CLOSED_REMOTELY)
                {
                    // close the socket
                    Close();
                    FatalException(this, new FatalEventArgs(
                                       ExceptionType.RECEIVE_FAILED, e));
                    throw e;
                }
                else if (SocketError.GetStatus(e.HResult) == SocketErrorStatus.Unknown)
                {
                    // If this is an unknown status it means that the error if fatal and retry will likely fail.
                    FatalException(this, new FatalEventArgs(
                                       ExceptionType.SEND_FAILED, e));
                    throw;
                }
                else
                {
                    NonFatalException(this, new NonFatalEventArgs(
                                          ExceptionType.SEND_FAILED, e));

                    // attempt to send again
                    awaitable = Send(data, numAttempts + 1);
                }
            }

            // wait for tasks to finish
            if (awaitable != null)
            {
                await awaitable;
            }

            // did the timer pop before the send could be completed?
            if (timerPopped)
            {
                throw new TimeoutException("Timeout on sending");
            }

            return(true);
        }
Example #2
0
        /// <summary>
        /// Attempt a TCP socket connection to the given host over the given port
        /// </summary>
        /// <param name="hostName">The name of the host</param>
        /// <param name="portNumber">The port number to connect</param>
        /// <param name="numAttempts">The number of times a connection has already been tried</param>
        /// <returns>True if the connection succeeds</returns>
        private async Task <bool> Connect(string hostName, int portNumber, int numAttempts)
        {
            PrintLine();

            System.Diagnostics.Debug.WriteLine(String.Format("connecting: {0}, {1}, {2}", hostName, portNumber, numAttempts));
            string result = string.Empty;

            lastHostName   = hostName;
            lastPortNumber = portNumber;

            // check the number of attempts
            if (numAttempts >= MAX_CONNECT_ATTEMPTS)
            {
                PrintLine();
                var e = new TimeoutException("Too many attempts to connect to remote server");
                FatalException(this, new FatalEventArgs(
                                   ExceptionType.CONNECTION_NOT_ESTABLISHED, e));
                throw e;
            }

            // initialize some values
            Task <bool>  awaitable   = null;
            StreamSocket newSocket   = new StreamSocket();
            bool         timerPopped = false;

            // connect to the remote end
            try
            {
                var timer = new AwaitTimer(3000);
                timerPopped = !timer.timeTask(newSocket.ConnectAsync(
                                                  new HostName(hostName),
                                                  portNumber.ToString(),
                                                  SocketProtectionLevel.PlainSocket));
            }
            catch (ArgumentException e)
            {
                NonFatalException(this, new NonFatalEventArgs(
                                      ExceptionType.HOSTNAME_INVALID, e));

                // attempt to reconnect
                awaitable = Connect(hostName, portNumber, numAttempts + 1);
            }
            catch (Exception e)
            {
                // If this is an unknown status it means that the error is fatal and retry will likely fail.
                if (SocketError.GetStatus(e.HResult) == SocketErrorStatus.Unknown)
                {
                    PrintLine();
                    FatalException(this, new FatalEventArgs(
                                       ExceptionType.CONNECTION_NOT_ESTABLISHED, e));
                    throw;
                }
                else
                {
                    NonFatalException(this, new NonFatalEventArgs(
                                          ExceptionType.CONNECTION_NOT_ESTABLISHED, e));

                    // attempt to reconnect
                    awaitable = Connect(hostName, portNumber, numAttempts + 1);
                }
            }

            // wait for all async connection attempts
            if (awaitable != null)
            {
                await awaitable;
            }

            // did the timer pop? throw an error!
            if (timerPopped)
            {
                PrintLine();
                newSocket.Dispose();
                throw new TimeoutException("Timeout on connecting");
            }

            // Check that the socket doesn't already exist
            if (_socket != null)
            {
                Close();
            }

            // establish the socket
            _socket     = newSocket;
            _dataWriter = new DataWriter(_socket.OutputStream);
            _dataReader = new DataReader(_socket.InputStream);
            activeListenerIDs.Add(activeListenerIDs.Count, true);

            // send/receive the alignment messages and
            // listen for incoming messages
            ListenForMessages(null, null, activeListenerIDs.Count - 1);

            PrintLine();
            System.Diagnostics.Debug.WriteLine("new socket: " + newSocket);

            return(true);
        }