async Task FlushAsync(bool doAsync, CancellationToken cancellationToken) { CheckDisposed(); if (outputIndex == 0) { return; } try { if (doAsync) { await Stream.WriteAsync(output, 0, outputIndex, cancellationToken).ConfigureAwait(false); await Stream.FlushAsync(cancellationToken).ConfigureAwait(false); } else { var network = NetworkStream.Get(Stream); network?.Poll(SelectMode.SelectWrite, cancellationToken); Stream.Write(output, 0, outputIndex); Stream.Flush(); } logger.LogClient(output, 0, outputIndex); outputIndex = 0; } catch (Exception ex) { IsConnected = false; if (!(ex is OperationCanceledException)) { cancellationToken.ThrowIfCancellationRequested(); } throw; } }
public void TestCanReadWriteSeekTimeout() { using (var stream = new NetworkStream(socket, false)) { Assert.IsTrue(stream.CanRead, "CanRead"); Assert.IsTrue(stream.CanWrite, "CanWrite"); Assert.IsFalse(stream.CanSeek, "CanSeek"); Assert.IsTrue(stream.CanTimeout, "CanTimeout"); } }
public void TestNotSupportedExceptions() { using (var stream = new NetworkStream(socket, false)) { Assert.Throws <NotSupportedException> (() => { var x = stream.Length; }); Assert.Throws <NotSupportedException> (() => stream.SetLength(512)); Assert.Throws <NotSupportedException> (() => { var x = stream.Position; }); Assert.Throws <NotSupportedException> (() => { stream.Position = 512; }); Assert.Throws <NotSupportedException> (() => stream.Seek(512, SeekOrigin.Begin)); } }
public void TestTimeouts() { using (var stream = new NetworkStream(socket, false)) { Assert.AreEqual(Timeout.Infinite, stream.ReadTimeout, "ReadTimeout #1"); Assert.Throws <ArgumentOutOfRangeException> (() => stream.ReadTimeout = 0); Assert.Throws <ArgumentOutOfRangeException> (() => stream.ReadTimeout = -2); stream.ReadTimeout = 500; Assert.AreEqual(500, stream.ReadTimeout, "ReadTimeout #2"); stream.ReadTimeout = Timeout.Infinite; Assert.AreEqual(Timeout.Infinite, stream.ReadTimeout, "ReadTimeout #3"); Assert.AreEqual(Timeout.Infinite, stream.WriteTimeout, "WriteTimeout #1"); Assert.Throws <ArgumentOutOfRangeException> (() => stream.WriteTimeout = 0); Assert.Throws <ArgumentOutOfRangeException> (() => stream.WriteTimeout = -2); stream.WriteTimeout = 500; Assert.AreEqual(500, stream.WriteTimeout, "WriteTimeout #2"); stream.WriteTimeout = Timeout.Infinite; Assert.AreEqual(Timeout.Infinite, stream.WriteTimeout, "WriteTimeout #3"); } }
async Task WriteAsync(byte[] buffer, int offset, int count, bool doAsync, CancellationToken cancellationToken) { CheckDisposed(); ValidateArguments(buffer, offset, count); try { var network = NetworkStream.Get(Stream); int index = offset; int left = count; while (left > 0) { int n = Math.Min(BlockSize - outputIndex, left); if (outputIndex > 0 || n < BlockSize) { // append the data to the output buffer Buffer.BlockCopy(buffer, index, output, outputIndex, n); outputIndex += n; index += n; left -= n; } if (outputIndex == BlockSize) { // flush the output buffer if (doAsync) { await Stream.WriteAsync(output, 0, BlockSize, cancellationToken).ConfigureAwait(false); } else { network?.Poll(SelectMode.SelectWrite, cancellationToken); Stream.Write(output, 0, BlockSize); } logger.LogClient(output, 0, BlockSize); outputIndex = 0; } if (outputIndex == 0) { // write blocks of data to the stream without buffering while (left >= BlockSize) { if (doAsync) { await Stream.WriteAsync(buffer, index, BlockSize, cancellationToken).ConfigureAwait(false); } else { network?.Poll(SelectMode.SelectWrite, cancellationToken); Stream.Write(buffer, index, BlockSize); } logger.LogClient(buffer, index, BlockSize); index += BlockSize; left -= BlockSize; } } } } catch (Exception ex) { IsConnected = false; if (!(ex is OperationCanceledException)) { cancellationToken.ThrowIfCancellationRequested(); } throw; } }
async Task AcceptProxyConnection(Socket socket, CancellationToken cancellationToken) { using (var client = new NetworkStream(socket, true)) { var buffer = new byte[4096]; Socket remote = null; int nread; while ((nread = await client.ReadAsync(buffer, 0, buffer.Length, cancellationToken).ConfigureAwait(false)) > 0) { try { remote = await ClientCommandReceived(client, buffer, nread, cancellationToken).ConfigureAwait(false); if (remote != null) { break; } } catch { return; } } if (remote == null) { return; } try { using (var server = new NetworkStream(remote, true)) { do { while (client.DataAvailable || server.DataAvailable) { if (client.DataAvailable) { if ((nread = await client.ReadAsync(buffer, 0, buffer.Length, cancellationToken).ConfigureAwait(false)) > 0) { await server.WriteAsync(buffer, 0, nread, cancellationToken).ConfigureAwait(false); } } if (server.DataAvailable) { if ((nread = await server.ReadAsync(buffer, 0, buffer.Length, cancellationToken).ConfigureAwait(false)) > 0) { await client.WriteAsync(buffer, 0, nread, cancellationToken).ConfigureAwait(false); } } } var checkRead = new ArrayList(); checkRead.Add(socket); checkRead.Add(remote); var checkError = new ArrayList(); checkError.Add(socket); checkError.Add(remote); Socket.Select(checkRead, null, checkError, 250000); cancellationToken.ThrowIfCancellationRequested(); } while (socket.Connected && remote.Connected); } } catch (OperationCanceledException) { return; } catch (SocketException) { return; } } }
protected abstract Task <Socket> ClientCommandReceived(NetworkStream client, byte[] buffer, int length, CancellationToken cancellationToken);
protected virtual Task <Stream> GetClientStreamAsync(Socket socket, CancellationToken cancellationToken) { Stream stream = new NetworkStream(socket, true); return(Task.FromResult(stream)); }