private async Task <TimeSpan> PingAsync(INetworkStream stream, CancellationToken cancellationToken) { var buffer = new byte[PingSize]; using (var rng = RandomNumberGenerator.Create()) { rng.GetNonZeroBytes(buffer); } var sw = new Stopwatch(); sw.Start(); if (await stream.WriteAsync(buffer, 0, buffer.Length, cancellationToken) != buffer.Length) { return(TimeSpan.Zero); } var rbuf = new byte[PingSize]; if (await stream.ReadFullAsync(rbuf, cancellationToken: cancellationToken) != rbuf.Length) { return(TimeSpan.Zero); } if (!rbuf.SequenceEqual(buffer)) { return(TimeSpan.Zero); } sw.Stop(); return(sw.Elapsed); }
/// <summary> /// Write a list of byte array segments. /// </summary> /// <param name="buffers">The list of array segment buffers to write.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>A task that asynchronously performs the operation.</returns> public async Task WriteAsync(IReadOnlyList <ArraySegment <byte> > buffers, CancellationToken cancellationToken = default) { foreach (var buffer in buffers) { await _stream.WriteAsync(buffer.Array, buffer.Offset, buffer.Count, cancellationToken).ConfigureAwait(false); cancellationToken.ThrowIfCancellationRequested(); } }
public async Task GivenAFakedSocketACallToWriteShouldBeRelayed() { string writtenString = Guid.NewGuid().ToString(); ISocket socket = A.Fake <ISocket>(); INetworkStream stream = A.Fake <INetworkStream>(); A.CallTo(() => socket.GetStream()).Returns(stream); TcpByteStream sut = new TcpByteStream(socket); CancellationToken cancellationToken = new CancellationToken(); await sut.WriteAsync(writtenString, cancellationToken).ConfigureAwait(false); A.CallTo(() => stream.WriteAsync(A <byte[]> .Ignored, 0, writtenString.Length, cancellationToken)).MustHaveHappened(); }
/// <summary> /// Asynchrnously sends a frame over the connection /// </summary> /// <param name="type">DEBUG ONLY: The type of the frame being sent</param> /// <param name="frame">The binary of the frame to be sent</param> private void _sendFrame(FrameType type, byte[] frame) { if (State == ConnectionState.End || State == ConnectionState.ConnectionError) { return; } try { Log.DebugFormat("[{0}] Sending frame: Type [{1}]", ID, type.ToString()); _networkStream.WriteAsync(frame, 0, frame.Length, _cts.Token).ConfigureAwait(false); } catch (Exception) { // change connection state to errored first State = ConnectionState.ConnectionError; // close dependent components and resources _closeInternal(); // raise the OnError event - application should call Dispose() OnError?.Invoke(this, null); } }
/// <summary> /// Relay all received by one stream to another stream. /// </summary> public static Task RelayToAsync( this INetworkStream readStream, INetworkStream writeStream, CancellationToken token) { return(Task.Run(async() => { // Use a buffer that is as large as possible, but does not exceed // any of the two stream's capabilities. int bufferSize = Math.Min( writeStream.MaxWriteSize, Math.Max( MaxBufferSize, readStream.MinReadSize)); var buffer = new byte[bufferSize]; while (true) { token.ThrowIfCancellationRequested(); try { TraceSources.Compute.TraceVerbose( "NetworkStream [{0} > {1}]: Reading...", readStream, writeStream); int bytesRead = await readStream.ReadAsync( buffer, 0, buffer.Length, token).ConfigureAwait(false); if (bytesRead > 0) { TraceSources.Compute.TraceVerbose( "NetworkStream [{0} > {1}]: Relaying {2} bytes", readStream, writeStream, bytesRead); await writeStream.WriteAsync(buffer, 0, bytesRead, token).ConfigureAwait(false); } else { TraceSources.Compute.TraceVerbose( "NetworkStream [{0} > {1}]: gracefully closed connection", readStream, writeStream); // Propagate. await writeStream.CloseAsync(token).ConfigureAwait(false); break; } } catch (NetworkStreamClosedException e) { TraceSources.Compute.TraceWarning( "NetworkStream [{0} > {1}]: forcefully closed connection: {2}", readStream, writeStream, e.Message); // Propagate. await writeStream.CloseAsync(token).ConfigureAwait(false); break; } catch (Exception e) { TraceSources.Compute.TraceWarning( "NetworkStream [{0} > {1}]: Caught unhandled exception: {2} {3}", readStream, writeStream, e.Message, e.StackTrace); throw; } } })); }
public Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) { Console.WriteLine(Encoding.ASCII.GetString(buffer, offset, count)); return(_innerStream.WriteAsync(buffer, offset, count, cancellationToken)); }
static Task WriteAsync(INetworkStream stream, byte[] data, CancellationToken cancellationToken) => stream.WriteAsync(data, 0, data.Length, cancellationToken);