/// <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]); }
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)); } }
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}"); }
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)); } }