From acaab92df987ad9fcd6c84c2afae9512b3efeb0b Mon Sep 17 00:00:00 2001 From: Gert Driesen Date: Mon, 6 Oct 2014 17:01:24 +0000 Subject: [PATCH] Add draft of ChannelDirectTcpip for Silverlight. --- .../ChannelDirectTcpip.SilverlightShared.cs | 72 +++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 Renci.SshClient/Renci.SshNet.Silverlight/Channels/ChannelDirectTcpip.SilverlightShared.cs diff --git a/Renci.SshClient/Renci.SshNet.Silverlight/Channels/ChannelDirectTcpip.SilverlightShared.cs b/Renci.SshClient/Renci.SshNet.Silverlight/Channels/ChannelDirectTcpip.SilverlightShared.cs new file mode 100644 index 00000000..7e0a3b88 --- /dev/null +++ b/Renci.SshClient/Renci.SshNet.Silverlight/Channels/ChannelDirectTcpip.SilverlightShared.cs @@ -0,0 +1,72 @@ +using System.Net.Sockets; +using System.Threading; + +namespace Renci.SshNet.Channels +{ + internal partial class ChannelDirectTcpip + { + private readonly AutoResetEvent _sendEvent = new AutoResetEvent(false); + private readonly AutoResetEvent _receiveEvent = new AutoResetEvent(false); + + partial void InternalSocketReceive(byte[] buffer, ref int read) + { + var bytesToRead = buffer.Length; + var receivedTotal = 0; // how many bytes is already received + + do + { + var args = new SocketAsyncEventArgs(); + args.SetBuffer(buffer, receivedTotal, bytesToRead - receivedTotal); + args.UserToken = _socket; + args.RemoteEndPoint = _socket.RemoteEndPoint; + args.Completed += OnReceive; + _socket.ReceiveAsync(args); + + _receiveEvent.WaitOne(ConnectionInfo.Timeout); + + if (args.SocketError == SocketError.WouldBlock || + args.SocketError == SocketError.IOPending || + args.SocketError == SocketError.NoBufferSpaceAvailable) + { + // socket buffer is probably empty, wait and try again + Thread.Sleep(30); + continue; + } + + if (args.SocketError != SocketError.Success) + { + throw new SocketException((int)args.SocketError); + } + + var receivedBytes = args.BytesTransferred; + if (receivedBytes > 0) + { + receivedTotal += receivedBytes; + continue; + } + break; + } while (receivedTotal < bytesToRead); + } + + partial void InternalSocketSend(byte[] data) + { + var args = new SocketAsyncEventArgs(); + args.SetBuffer(data, 0, data.Length); + args.UserToken = _socket; + args.RemoteEndPoint = _socket.RemoteEndPoint; + args.Completed += OnSend; + _socket.SendAsync(args); + _sendEvent.WaitOne(ConnectionInfo.Timeout); + } + + private void OnReceive(object sender, SocketAsyncEventArgs e) + { + _receiveEvent.Set(); + } + + private void OnSend(object sender, SocketAsyncEventArgs e) + { + _sendEvent.Set(); + } + } +}