/// <summary>
        /// Reads the incoming socket, returning just the first line (based on CRLF). The rest of the data is ignored.
        /// </summary>
        /// <param name="tcpSocket"></param>
        /// <returns></returns>
        private async Task <String> ReadIncomingCommandLineAsync(StreamSocket tcpSocket)
        {
            var s      = tcpSocket.InputStream;
            var buffer = new Windows.Storage.Streams.Buffer(2048);

            string stringresult = "";
            var    keepGoing    = true;

            while (keepGoing)
            {
                try
                {
                    var readTask = s.ReadAsync(buffer, buffer.Capacity, InputStreamOptions.Partial);
                    var taskList = new Task[]
                    {
                        readTask.AsTask(),
                        Task.Delay(Options.TcpReadTimeInMilliseconds),
                    };
                    var waitResult = await Task.WhenAny(taskList);

                    if (waitResult == taskList[0])
                    {
                        var result = readTask.GetResults();
                        Stats.NBytesRead += result.Length;
                        var options       = BufferToString.ToStringOptions.ProcessCrLf | BufferToString.ToStringOptions.ProcessTab;
                        var partialresult = BufferToString.ToString(result, options);
                        stringresult += partialresult;
                        Log($"Got data from client: {stringresult} Length={result.Length}");
                    }
                    else
                    {
                        keepGoing = false; // Timed out
                    }
                }
                catch (Exception ex2)
                {
                    Stats.NExceptions++;
                    keepGoing = false;
                    Log($"EXCEPTION while reading: {ex2.Message} {ex2.HResult:X}");
                }
            }
            var split = stringresult.Split("\r\n", 2); //NOTE: alternative is to split at either CR or LF

            return(split[0]);
        }
Пример #2
0
        private EchoResult ReadUdp(DataReader dr)
        {
            uint count = dr.UnconsumedBufferLength;

            if (count > 0)
            {
                byte[] buffer = new byte[dr.UnconsumedBufferLength];
                dr.ReadBytes(buffer);
                var stringresult = BufferToString.ToString(buffer);
                LogEchoBuffer(buffer);
                var delta = DateTime.UtcNow.Subtract(SocketStartTime).TotalSeconds;
                return(EchoResult.MakeSucceeded(stringresult, delta));
            }
            else // socket is done
            {
                var delta = DateTime.UtcNow.Subtract(SocketStartTime).TotalSeconds;
                return(EchoResult.MakeFailed(SocketErrorStatus.HttpInvalidServerResponse, delta));
            }
        }
Пример #3
0
        public static async Task <DrainStreamResult> DrainStream(StreamSocket tcpSocket, int tcpReadTimeInMilliseconds)
        {
            var retval = new DrainStreamResult();
            var s      = tcpSocket.InputStream;
            var buffer = new Windows.Storage.Streams.Buffer(2048);

            string stringresult = "";
            var    keepGoing    = tcpReadTimeInMilliseconds >= 0; // Read time is negative? Then don't read at all!

            while (keepGoing)
            {
                try
                {
                    var readTask = s.ReadAsync(buffer, buffer.Capacity, InputStreamOptions.Partial);
                    var taskList = new Task[]
                    {
                        readTask.AsTask(),
                        Task.Delay(tcpReadTimeInMilliseconds),
                    };
                    var waitResult = await Task.WhenAny(taskList);

                    if (waitResult == taskList[0])
                    {
                        var result = readTask.GetResults();
                        retval.NBytesRead += result.Length;
                        var partialresult = BufferToString.ToString(result);
                        stringresult   += partialresult;
                        retval.LogText += $"Got data from client: {stringresult} Length={result.Length}\n";
                    }
                    else
                    {
                        keepGoing = false;
                    }
                }
                catch (Exception ex2)
                {
                    retval.NExceptions++;
                    keepGoing       = false;
                    retval.LogText += $"EXCEPTION while reading: {ex2.Message} {ex2.HResult:X}\n";
                }
            }
            return(retval);
        }
        private async Task CharGenReadTcpAsync(StreamSocket tcpSocket, CancellationToken ct)
        {
            // Continuously read in all information
            var s      = tcpSocket.InputStream;
            var buffer = new Windows.Storage.Streams.Buffer(2048);

            var readOk = true;

            while (readOk && !ct.IsCancellationRequested)
            {
                try
                {
                    var readTask = s.ReadAsync(buffer, buffer.Capacity, InputStreamOptions.Partial);
                    var taskList = new Task[]
                    {
                        readTask.AsTask(),
                        Task.Delay(Options.TcpReadPollTimeInMilliseconds)
                    };
                    var waitResult = await Task.WhenAny(taskList);

                    if (waitResult == taskList[0])
                    {
                        var result = readTask.GetResults();
                        Stats.NBytesRead += result.Length;
                        if (result.Length == 0)
                        {
                            readOk = false; // Client must have closed the socket; stop the server
                        }
                        var partialresult = BufferToString.ToString(result);
                    }
                    else
                    {
                        // Done with this polling loop
                    }
                }
                catch (Exception ex2)
                {
                    Stats.NExceptions++;
                    readOk = false;
                    Log($"EXCEPTION while reading: {ex2.Message} {ex2.HResult:X}");
                }
            }
        }
        private DaytimeResult ReadUdp(DataReader dr) //TODO: directly read buffer instead of weirding out the DataReader?
        {
            uint count = dr.UnconsumedBufferLength;

            if (count > 0)
            {
                byte[] buffer = new byte[dr.UnconsumedBufferLength];
                dr.ReadBytes(buffer);
                var stringresult = BufferToString.ToString(buffer);
                Log($"{stringresult}"); // Will be printed on the screen.
                var delta = DateTime.UtcNow.Subtract(UdpStartTime).TotalSeconds;
                return(DaytimeResult.MakeSucceeded(stringresult, delta));
            }
            else
            {
                var stringresult = "ERROR:No results!";
                Log($"DAYTIME: CLIENT:{stringresult}");
                var delta = DateTime.UtcNow.Subtract(UdpStartTime).TotalSeconds;
                return(DaytimeResult.MakeFailed(SocketErrorStatus.HttpInvalidServerResponse, delta));
            }
        }
        private async Task DaytimeUdpAsync(DataReader dr, DataWriter dw, string remotePort)
        {
            // Step 1 is to write the reply.
            // Step 2 is to read (and discard) all incoming data from the single UDP packet
            var time = DateTime.Now;
            var str  = time.ToString(Options.DateTimeFormat); // "F" is the default


            string suffix = "";

            if (dr != null) // Will always be present for normal packets
            {
                uint count = dr.UnconsumedBufferLength;
                if (count > 0)
                {
                    Stats.NBytesRead += count;
                    byte[] buffer = new byte[count];
                    dr.ReadBytes(buffer);
                    var stringresult = BufferToString.ToString(buffer);
                    suffix = stringresult;
                    Log(ServerOptions.Verbosity.Verbose, $"SERVER: UDP read {count} bytes {stringresult}");
                }
            }

            str = str + suffix;
            Log(ServerOptions.Verbosity.Verbose, $"SERVER: UDP: reply with daytime <<{str}>> to remote port {remotePort}");
            dw.WriteString(str);
            await dw.StoreAsync();

            await dw.FlushAsync(); // NOTE: this flush doesn't actually do anything useful

            Stats.IncrementNResponses();

            dw.Dispose();
            Log(ServerOptions.Verbosity.Verbose, $"SERVER: UDP closing down the current writing socket for {str}");
        }
Пример #7
0
        public async Task <FingerResult> WriteAsync(ParsedFingerCommand request)
        {
            var data     = request.ToString();
            var datanice = data.Replace("\r\n", "");

            datanice = string.IsNullOrEmpty(datanice) ? "<blank string>" : datanice;

            var startTime = DateTime.UtcNow;

            try
            {
                var tcpSocket   = new StreamSocket();
                var connectTask = tcpSocket.ConnectAsync(request.SendToHost, request.SendToPort);

                var taskList = new Task[]
                {
                    connectTask.AsTask(),
                    Task.Delay(Options.MaxConnectTimeInMilliseconds)
                };
                var waitResult = await Task.WhenAny(taskList);

                if (waitResult == taskList[1])
                {
                    Stats.NExceptions++; // mark it as an exception -- it would have failed if we didn't time out
                    Log($"TIMEOUT while connecting to {request.SendToHost} {request.SendToPort}");
                    Log($"Unable to send command {datanice}\n");

                    var faildelta = DateTime.UtcNow.Subtract(startTime).TotalSeconds;
                    return(FingerResult.MakeFailed(SocketErrorStatus.ConnectionTimedOut, faildelta));
                }
                else
                {
                    // Connect is OK
                    if (!string.IsNullOrEmpty(data))
                    {
                        var dw = new DataWriter(tcpSocket.OutputStream);
                        dw.WriteString(data);
                        await dw.StoreAsync();

                        Log(ClientOptions.Verbosity.Normal, $"Finger sending command {datanice}\n");
                    }
                    Stats.NWrites++;

                    // Now read everything
                    var s      = tcpSocket.InputStream;
                    var buffer = new Windows.Storage.Streams.Buffer(1024 * 64); // read in lots of the data

                    string stringresult = "";
                    var    keepGoing    = true;
                    while (keepGoing)
                    {
                        try
                        {
                            var read = s.ReadAsync(buffer, buffer.Capacity, InputStreamOptions.Partial);

                            /* This is the syntax that the editor will suggest. There's a
                             * much simpler syntax (below) that's syntactic sugar over this.
                             * read.Progress = new AsyncOperationProgressHandler<IBuffer, uint>(
                             *  (operation, progress) =>
                             *  {
                             *      var err = operation.ErrorCode == null ? "null" : operation.ErrorCode.ToString();
                             *      Log(ClientOptions.Verbosity.Verbose, $"Daytime Progress count={progress} status={operation.Status} errorcode={err}");
                             *  });
                             */
                            read.Progress = (operation, progress) =>
                            {
                                var err = operation.ErrorCode == null ? "null" : operation.ErrorCode.ToString();
                                Log(ClientOptions.Verbosity.Verbose, $"Finger Progress count={progress} status={operation.Status} errorcode={err}");
                            };
                            var result = await read;
                            if (result.Length != 0)
                            {
                                var options       = BufferToString.ToStringOptions.ProcessCrLf | BufferToString.ToStringOptions.ProcessTab;
                                var partialresult = BufferToString.ToString(result, options);
                                stringresult += partialresult;
                                Log($"{partialresult}"); // This will be printed on the user's screen.
                            }
                            else
                            {
                                keepGoing = false;
                                Log(ClientOptions.Verbosity.Verbose, $"Read completed with zero bytes; closing");
                            }
                        }
                        catch (Exception ex2)
                        {
                            keepGoing = false;
                            Stats.NExceptions++;
                            Log($"EXCEPTION while reading: {ex2.Message} {ex2.HResult:X}");

                            var faildelta = DateTime.UtcNow.Subtract(startTime).TotalSeconds;
                            return(FingerResult.MakeFailed(ex2, faildelta));
                        }
                    }

                    var delta = DateTime.UtcNow.Subtract(startTime).TotalSeconds;
                    return(FingerResult.MakeSucceeded(stringresult, delta));
                }
            }
            catch (Exception ex)
            {
                Stats.NExceptions++;
                Log($"ERROR: Client: Writing {datanice} to {request.SendToHost} exception {ex.Message}");
                var delta = DateTime.UtcNow.Subtract(startTime).TotalSeconds;
                return(FingerResult.MakeFailed(ex, delta));
            }
        }
        private async Task DaytimeTcpAsync(StreamSocket tcpSocket)
        {
            // Step 1 is to write the reply.
            // Step 2 is to read (and discard) all incoming data
            var time = DateTime.Now;
            var str  = time.ToString(Options.DateTimeFormat); // "F" is the default

            //NOTE: here's how to write data using a DataWriter
            //var dw = new DataWriter(tcpSocket.OutputStream);
            //dw.WriteString(str);
            //await dw.StoreAsync();
            Stats.IncrementNResponses();
            //await dw.FlushAsync(); // NOTE: this flush doesn't actually do anything useful.

            uint totalBytesWrite = 0;
            var  writeBuffer     = Windows.Security.Cryptography.CryptographicBuffer.ConvertStringToBinary(str, Windows.Security.Cryptography.BinaryStringEncoding.Utf8);
            var  writeTask       = tcpSocket.OutputStream.WriteAsync(writeBuffer);
            var  bytesToWrite    = writeBuffer.Length;

            writeTask.Progress += (operation, progress) =>
            {
                totalBytesWrite = progress;
            };
            await tcpSocket.OutputStream.FlushAsync();


            // Now read in all of the data that might have been passed but only for a little while.
            // Daytime doesn't use this information at all.
            var s      = tcpSocket.InputStream;
            var buffer = new Windows.Storage.Streams.Buffer(2048);

            string stringresult = "";
            var    keepGoing    = Options.TcpReadTimeInMilliseconds >= 0; // Read time is negative? Then don't read at all!

            while (keepGoing)
            {
                try
                {
                    var readTask = s.ReadAsync(buffer, buffer.Capacity, InputStreamOptions.Partial);
                    var taskList = new Task[]
                    {
                        readTask.AsTask(),
                        Task.Delay(Options.TcpReadTimeInMilliseconds),
                    };
                    var waitResult = await Task.WhenAny(taskList);

                    if (waitResult == taskList[0])
                    {
                        var result = readTask.GetResults();
                        Stats.NBytesRead += result.Length;
                        var partialresult = BufferToString.ToString(result);
                        stringresult += partialresult;
                        Log($"Got data from client: {stringresult} Length={result.Length}");
                    }
                    else
                    {
                        keepGoing = false; // Timed out.
                    }
                }
                catch (Exception ex2)
                {
                    Stats.NExceptions++;
                    keepGoing = false;
                    Log($"EXCEPTION while reading: {ex2.Message} {ex2.HResult:X}");
                }
            }

            Log(ServerOptions.Verbosity.Verbose, $"SERVER: TCP Stream closing down the current writing socket");

            // Wait for the write buffer to be completely written, but only wait a short while.
            // The actual progress is limited because not all writes will trigger the progress indicator.
            // Works fine with no waiting (WriteTimeInMilliseconds set to -1)
            int currWait = 0;

            while (totalBytesWrite != bytesToWrite && currWait < Options.TcpWriteTimeInMilliseconds)
            {
                await Task.Delay(10);

                currWait += 10;
            }
            if (totalBytesWrite != bytesToWrite && Options.TcpWriteTimeInMilliseconds >= 0)
            {
                Log(ServerOptions.Verbosity.Verbose, $"SERVER: incomplete write {totalBytesWrite} of {bytesToWrite} wait time {Options.TcpWriteTimeInMilliseconds}");
            }

            if (Options.TcpPauseBeforeCloseTimeInMilliseconds >= 0)
            {
                await Task.Delay(Options.TcpPauseBeforeCloseTimeInMilliseconds);
            }
            tcpSocket.Dispose(); // The dispose is critical; without it the client won't ever finish reading our output
        }
        private async Task <DaytimeResult> WriteTcpAsync(HostName address, string service, string data)
        {
            var startTime = DateTime.UtcNow;

            try
            {
                var tcpSocket = new StreamSocket();
                await tcpSocket.ConnectAsync(address, service);

                // Everything that's sent will be ignored.
                if (!string.IsNullOrEmpty(data))
                {
                    var dw = new DataWriter(tcpSocket.OutputStream);
                    dw.WriteString(data);
                    await dw.StoreAsync();
                }
                Stats.NWrites++;

                // Now read everything
                var s      = tcpSocket.InputStream;
                var buffer = new Windows.Storage.Streams.Buffer(2048);

                string stringresult = "";
                var    keepGoing    = true;
                while (keepGoing)
                {
                    try
                    {
                        var read = s.ReadAsync(buffer, buffer.Capacity, InputStreamOptions.Partial);

                        /* This is the syntax that the editor will suggest. There's a
                         * much simpler syntax (below) that's syntactic sugar over this.
                         * read.Progress = new AsyncOperationProgressHandler<IBuffer, uint>(
                         *  (operation, progress) =>
                         *  {
                         *      var err = operation.ErrorCode == null ? "null" : operation.ErrorCode.ToString();
                         *      Log(ClientOptions.Verbosity.Verbose, $"Daytime Progress count={progress} status={operation.Status} errorcode={err}");
                         *  });
                         */
                        read.Progress = (operation, progress) =>
                        {
                            var err = operation.ErrorCode == null ? "null" : operation.ErrorCode.ToString();
                            Log(ClientOptions.Verbosity.Verbose, $"Daytime Progress count={progress} status={operation.Status} errorcode={err}");
                        };
                        var result = await read;
                        if (result.Length != 0)
                        {
                            var partialresult = BufferToString.ToString(result);
                            stringresult += partialresult;
                            Log($"{stringresult}"); // This will be printed on the user's screen.
                        }
                        else
                        {
                            keepGoing = false;
                            Log(ClientOptions.Verbosity.Verbose, $"Read completed with zero bytes; closing");
                        }
                    }
                    catch (Exception ex2)
                    {
                        keepGoing = false;
                        Stats.NExceptions++;
                        Log($"EXCEPTION while reading: {ex2.Message} {ex2.HResult:X}");

                        var faildelta = DateTime.UtcNow.Subtract(startTime).TotalSeconds;
                        return(DaytimeResult.MakeFailed(ex2, faildelta));
                    }
                }

                var delta = DateTime.UtcNow.Subtract(startTime).TotalSeconds;
                return(DaytimeResult.MakeSucceeded(stringresult, delta));
            }
            catch (Exception ex)
            {
                Stats.NExceptions++;
                Log($"ERROR: Client: Writing {data} to {address} exception {ex.Message}");
                var delta = DateTime.UtcNow.Subtract(startTime).TotalSeconds;
                return(DaytimeResult.MakeFailed(ex, delta));
            }
        }