Преглед изворни кода

Fix SocketReadLine for Silverlight version to support multiple lines
Improve IsSocketConnected to determine wheither client is connected or not

olegkap_cp пре 13 година
родитељ
комит
2efef57b52

+ 23 - 20
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<byte>();
 
+            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<SocketAsyncEventArgs>(OnReceive);
                 this._socket.ReceiveAsync(args);
 
-                this._receiveEvent.WaitOne(this.ConnectionInfo.Timeout);
-
-                char lastChar = (char)buffer[0];
-                for (int i = 1; i < args.BytesTransferred; i++)
-                {
-                    char newChar = (char)buffer[i];
-                    if (lastChar == '\r' && newChar == '\n')
-                        break;
+                if (!this._receiveEvent.WaitOne(this.ConnectionInfo.Timeout))
+                    throw new SshOperationTimeoutException("Socket read operation has timed out");
 
-                    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)

+ 3 - 1
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)