diff --git a/Renci.SshClient/Renci.SshNet.Silverlight/Session.SilverlightShared.cs b/Renci.SshClient/Renci.SshNet.Silverlight/Session.SilverlightShared.cs index 2b41f84a..f6f4fd72 100644 --- a/Renci.SshClient/Renci.SshNet.Silverlight/Session.SilverlightShared.cs +++ b/Renci.SshClient/Renci.SshNet.Silverlight/Session.SilverlightShared.cs @@ -7,6 +7,7 @@ using Renci.SshNet.Common; using Renci.SshNet.Messages.Transport; using System.Text; using Renci.SshNet.Messages; +using System.Collections.Generic; namespace Renci.SshNet { @@ -48,40 +49,42 @@ namespace Renci.SshNet partial void SocketReadLine(ref string response) { - // TODO: Improve this function, currently will not work with server that send multiple lines as a first string + var encoding = new Renci.SshNet.Common.ASCIIEncoding(); - var buffer = new byte[1024]; - - StringBuilder result = new StringBuilder(); + var line = new StringBuilder(); + // Read data one byte at a time to find end of line and leave any unhandled information in the buffer to be processed later + var buffer = new List(); + var data = new byte[1]; do { SocketAsyncEventArgs args = new SocketAsyncEventArgs(); - args.SetBuffer(buffer, 0, buffer.Length); + args.SetBuffer(data, 0, data.Length); args.UserToken = this._socket; args.RemoteEndPoint = this._socket.RemoteEndPoint; args.Completed += new EventHandler(OnReceive); this._socket.ReceiveAsync(args); - this._receiveEvent.WaitOne(this.ConnectionInfo.Timeout); + if (!this._receiveEvent.WaitOne(this.ConnectionInfo.Timeout)) + throw new SshOperationTimeoutException("Socket read operation has timed out"); - char lastChar = (char)buffer[0]; - for (int i = 1; i < args.BytesTransferred; i++) - { - char newChar = (char)buffer[i]; - if (lastChar == '\r' && newChar == '\n') - break; - - result.Append(lastChar); - lastChar = newChar; - } - - if (args.BytesTransferred < buffer.Length) + // If zero bytes received then exit + if (args.BytesTransferred == 0) break; - } while (true); + buffer.Add(data[0]); + } + while (!(buffer.Count > 0 && (buffer[buffer.Count - 1] == 0x0A || buffer[buffer.Count - 1] == 0x00))); - response = result.ToString(); + // Return an empty version string if the buffer consists of a 0x00 character. + if (buffer.Count > 0 && buffer[buffer.Count - 1] == 0x00) + { + response = string.Empty; + } + else if (buffer.Count > 1 && buffer[buffer.Count - 2] == 0x0D) + response = encoding.GetString(buffer.ToArray(), 0, buffer.Count - 2); + else + response = encoding.GetString(buffer.ToArray(), 0, buffer.Count - 1); } partial void SocketRead(int length, ref byte[] buffer) diff --git a/Renci.SshClient/Renci.SshNet/Session.NET.cs b/Renci.SshClient/Renci.SshNet/Session.NET.cs index 797c75fc..9c440c70 100644 --- a/Renci.SshClient/Renci.SshNet/Session.NET.cs +++ b/Renci.SshClient/Renci.SshNet/Session.NET.cs @@ -24,7 +24,9 @@ namespace Renci.SshNet partial void IsSocketConnected(ref bool isConnected) { - isConnected = (!this._isDisconnecting && this._socket != null && this._socket.Connected && this._isAuthenticated && this._messageListenerCompleted != null) && !(this._socket.Poll(10, SelectMode.SelectRead)); + //isConnected = (!this._isDisconnecting && this._socket != null && this._socket.Connected && this._isAuthenticated && this._messageListenerCompleted != null) && !(this._socket.Poll(10, SelectMode.SelectRead)); + isConnected = (!this._isDisconnecting && this._socket != null && this._socket.Connected && this._isAuthenticated && this._messageListenerCompleted != null) + && !(this._socket.Poll(1, SelectMode.SelectRead) && this._socket.Available == 0); } partial void SocketConnect(string host, int port)