Buffer Size Command Hanging - WeOnlyDo Discussion board

Buffer Size Command Hanging (wodSSH / wodSSH.NET)

by mmorton, Tuesday, July 07, 2009, 14:32 (5619 days ago)

Hi,

I am issuing a command that returns 10000+ rows that I need to retrieve and parse.

If I connect to the server drectly and run the following command:

[code]
show * /identifier
[/code]

The commands completes in around 10 seconds.

When issuing the same command using the following code the code just hangs and a timeout occurs.

[code]
passwd = Split(sshConnection.Execute( show * /identifier & vbCrLf, UAF> , 300), vbCrLf)
[/code]

I have also tried the following command and it returns results but ends on or around 4000 rows.

[code]
sshConnection.Send( show * /identifier & vbCrLf)
While sshConnection.DataReady
passwd.Add(sshConnection.Recieve)
End While
[/code]

Any ideas on what could be causing this?
I can only assume that there is some kind of buffer limit and that is why the first command times out.

Thanks in advance
Mike

Re: Buffer Size Command Hanging

by wodDamir, Tuesday, July 07, 2009, 14:43 (5619 days ago) @ mmorton

Mike,

What if you try using non-blocking mode?

Can you try our TerminalWindows sample and check if the same occurs in it?

Regards,
Damba

Re: Buffer Size Command Hanging

by mmorton, Tuesday, July 07, 2009, 15:27 (5619 days ago) @ wodDamir

Hi,

Where can I find the example you refer to?

Also, can you enable blocking mode for the single command or do you enable before connecting?

Thanks
Mike

Re: Buffer Size Command Hanging

by wodDamir, Tuesday, July 07, 2009, 15:44 (5619 days ago) @ mmorton

Mike,

You are using wodSSH.Net, right?

If so, the samples are installed along with the installer, so you should have All Samples solution shortcut in your start menu.

When you open it, you should have Terminal CS Sample , and Terminal VB Sample .

As for Blocking, it can be changed during the active connection. However, please note that Events shouldn't be used in Blocking mode, since this could result in unexpected behaviour.

Regards,
Damba

Re: Buffer Size Command Hanging

by mmorton, Tuesday, July 07, 2009, 17:30 (5619 days ago) @ wodDamir

Hi,

I have looked at the example and I dont think that really helps me in what I am trying to do.

I have tried setting blocking to false for the command and it retrieves about 88 lines and then stops with 'Object not set to an Instance of an Object'.

I am not sure why it would raise this event as there is still plenty of data to go.

Here is the code I used.


[code]
sshConnection.Execute( show * /identifier & vbCrLf, vbCrLf, 30)
sshConnection.Blocking = False
While sshConnection.DataReady
Dim data_recieve As String = sshConnection.ReceiveLine.ToString
If data_recieve.Contains( [ ) And data_recieve.Contains( ] ) Then passwd.Add(data_recieve)
End While
sshConnection.Blocking = True
[/code]

The error occurs when I try to access the data_recieve string. ANy ideas?

Regards
Mike

Re: Buffer Size Command Hanging

by woddrazen, Tuesday, July 07, 2009, 17:41 (5619 days ago) @ mmorton

Mike,


Can you maybe try our Basic VB sample? That sample will connect to server and execute some command using Command Property.

In order to make it work for you. You should only change in sample code Ssh1.Command = ls -al & Chr(10) to:

Ssh1.Command = show * /identifier & vbCrLf

Also when you receive result in TextBox1 scroll bar is missing. So you will not see full response. If you wish you can add scroll bar using TexeBox1 ScrollBars Property.

Let us know how it goes.


Drazen

Re: Buffer Size Command Hanging

by mmorton, Tuesday, July 07, 2009, 17:56 (5619 days ago) @ woddrazen

Hi,

The example doesnt really help as I need to run a few other commands first to be able to get to the stage of issuing the long problematic command.

I am not really sure how the example differs to what I am doing so I guess I will just have to do work out another way of doing this.

Is there no known issues with recieving large amounts of data?

I have other commands that I run in the same way and output the result without errors but the only one that I have a problem with is the lengthy output. I can only assume from this that wodSSH.NET has a problem with recieving large amounts of data.

Regards
Mike

Re: Buffer Size Command Hanging

by woddrazen, Tuesday, July 07, 2009, 18:15 (5619 days ago) @ mmorton

Mike,


Sorry I didn't realize that you need to execute more then one command. Command Property is used to execute only one.

There shouldn't be problem with receiving large amount of data.

Is there any chance we can connect to your server and duplicate your problem?

You can send your private information to techsupport@weonlydo.com


Drazen

Re: Buffer Size Command Hanging

by mmorton, Tuesday, July 07, 2009, 18:21 (5619 days ago) @ woddrazen

No sorry the service is an internal production server.

Looking back over the last few posts though it seems like another person has the same issue with large amounts of data.

Titled: Using Execute/Receive method when CMD returns larg

Regards
Mike

Re: Buffer Size Command Hanging

by woddrazen, Tuesday, July 07, 2009, 18:49 (5619 days ago) @ mmorton

Mike,


Look like that issue is resolved. Can you try what is suggest in last reply there?

Also which version of wodSSH.NET you are using? You can check version using wodSSH.NET Version Property.


Drazen

Re: Buffer Size Command Hanging

by mmorton, Tuesday, July 07, 2009, 18:53 (5619 days ago) @ woddrazen

Hi,

I am using Version 2.4.0.98. I assume this is the latest version as I only downloaded it last week.

I have already what is suggested in that post and I still get the same problems.

This is getting slighlty frustrating.

Regards
Mike

Re: Buffer Size Command Hanging

by woddrazen, Tuesday, July 07, 2009, 20:08 (5619 days ago) @ mmorton

Mike,


Latest version is 2.4.4.144. Can you please download latest version and try it again?

I'm trying to duplicate your problem using our ssh test server.

Here is code I tried and it worked for me without any problem:[code]
...
ssh1.KeepAlives = True
ssh1.Connect()
MsgBox(ssh1.Version)

ssh1.WaitFor( regex:[$ #>] $ )
ssh1.DataReady = 0
Debug.Print(ssh1.Execute( cd /home/weonlydo/drazen/8000files + vbLf, regex:[$ #>] $ ))
ssh1.DataReady = 0
Debug.Print(ssh1.Execute( ls -ltR + vbLf, regex:[$ #>] $ ))
ssh1.Disconnect()
MsgBox( done )[/code]
Drazen

Re: Buffer Size Command Hanging

by mmorton, Tuesday, July 07, 2009, 20:53 (5619 days ago) @ woddrazen

Hi,

I have updated to the latest version as suggested.

The only difference between your code and mine was the KeepAlives=True. I have added this to my code but it makes no difference.

Regards
Mike

Re: Buffer Size Command Hanging

by mmorton, Tuesday, July 07, 2009, 21:23 (5619 days ago) @ mmorton

Hi,

I have managed to work out that the command is timing out because it takes ages to run the command. Is there any reason why it runs so slow.

For Example
If I run the command in Putty or Windows Telnet the command completes within about 10-15 seconds.
If I run the same command after 60 seconds which is far longer than running the command in the GUI I have only 2500 records within the buffer which is only a quarter of the records.

Why does the command take around 4 minutes more to complete the same task in the GUI?

Thanks
Mike

Re: Buffer Size Command Hanging

by woddrazen, Tuesday, July 07, 2009, 22:04 (5619 days ago) @ mmorton

Mike,


I think I was able to duplicate the issue.

I will now transfer this ticket to our developers to see if they can do the same in debug mode, and determine why this happens.

You should receive response from them when we have more about it.


Drazen

Re: Buffer Size Command Hanging

by wodSupport, Wednesday, July 08, 2009, 00:31 (5619 days ago) @ woddrazen

Mike,

I checked our source code, but I don't have good news about this issue. When large data is returned to Waitfor/Execute, on each new byte chunk that arrives from the server full search is made. Usually C++ code can do this fast, but in C# obviously looping through byte array takes time.

Even more, if regular expressions are used, bytes are converted to chars which are then converted to string - all of this takes CPU utilization.

In order to workaround this problem, I suggest you don't use Waitfor/Execute for this purpose, since they are too general. I can't tweak them since htey have to stay general enough, but you would have better luck by storing data that arrives to local buffer, and keep only last line that arrives. This way you can easily check the line if it contains whatever you provided to Waitfor/Execute in the first place.

Can you try that?

Regards,
Kreso

Re: Buffer Size Command Hanging

by mmorton, Wednesday, July 08, 2009, 10:28 (5618 days ago) @ wodSupport

Hi,

Yes, I can read it line by line although the regex functionality doesnt seem to work as it should.

If you read line by line I need to match vbCrLf and the end prompt UAF>. The expression for this is

[code]
regex:UAF>| & vbCrLF
[/code]

This kind of works and finds the line feed; however, it doesnt remove the vbCrLf from the buffer so it just goes into a loop because regex removes the string before the vbCrLf that was found. All remaining strings are blank.

The only other way of doing this is catching the timeout of matching just waitfor(vbCrLf). This isnt ideal as I shouldnt be expecting an exception every time and plus I would have to wait for the timeout each time.

Any ideas on why regex does not also remove the vbCrLf from the buffer?

Thanks
Mike

Re: Buffer Size Command Hanging

by wodDamir, Wednesday, July 08, 2009, 11:04 (5618 days ago) @ mmorton

Mike,

What if you try UAF>|\r\n for the regex string?

Regards,
Damba

Re: Buffer Size Command Hanging

by mmorton, Wednesday, July 08, 2009, 11:16 (5618 days ago) @ wodDamir

Hi,

vbCrLf works and so I dont need to change this.

For Example
If I have the following lines in the buffer.

String 1

String 2

String 3

String 4

String 5


The following regex expression works regex:UAF>|vbCrLF. The problem is the waitfor using this regex expression returns String 1. It leaves the
in the buffer so I end up with this.

String 2

String 3

String 4

String 5


Which means it then goes into a loop because it doesnt actually remove the carriage return from the buffer.

If I use waitfor(vbCrLF) it returns String 1
therefore removing the carriage return from the buffer.

Regards
Mike

Re: Buffer Size Command Hanging

by wodDamir, Wednesday, July 08, 2009, 11:29 (5618 days ago) @ mmorton

Mike,

Why not try setting DataReady property to 0 in such case? This would clear the buffer, thus preventing such behaviour.

Can you try that?

Regards,
Damba

Re: Buffer Size Command Hanging

by mmorton, Wednesday, July 08, 2009, 11:33 (5618 days ago) @ wodDamir

How can I do that without removing the other lines of data that I need?

I am reading line by line and so setting DataReady to 0 would remove all the other information that I need.

Re: Buffer Size Command Hanging

by wodDamir, Wednesday, July 08, 2009, 11:45 (5618 days ago) @ mmorton

Mike,

I'm a bit confused. Can you show me your Receive routine?

I believe what Kreso meant by receiving line-by-line was to use ReceiveLine method (and avoid WaitFor completely).

Regards,
Damba

Re: Buffer Size Command Hanging

by mmorton, Wednesday, July 08, 2009, 11:54 (5618 days ago) @ wodDamir

The code I am currently using is.

[code]
sshConnection.Execute( show * /identifier & vbCrLf, vbCrLf, 30)
Dim data_retrieve As Boolean = True
While data_retrieve
Dim line_data As String = sshConnection.WaitFor( regex:UAF>| & vbCrLf, 30)
If line_data.Contains( [ ) And line_data.Contains( ] ) Then
passwd.Add(line_data.Replace( , ))
Else
If line_data.Contains( UAF> ) Then data_retrieve = False
End If
End While
[/code]

I tried to use the following:

[code]
sshConnection.Blocking = False
sshConnection.Send( show * /identifier & vbCrLf)
While sshConnection.DataReady
Dim line_data As String = sshConnection.RecieveLine()
If line_data.Contains( [ ) And line_data.Contains( ] ) Then passwd.Add(line_data.Replace( , ))
End While
[/code]

But this code doesnt retrieve all the rows. It retrieves about 2000-3000 and produces different amounts each time. As the server has pauses in the output I had to start trying to use waitfor.

I am expecting 9874 rows.

Regards
Mike

Re: Buffer Size Command Hanging

by wodDamir, Wednesday, July 08, 2009, 12:03 (5618 days ago) @ mmorton

Mike,

Ok, let's sum this. Currently the problem that you have is that component doesn't automatically remove vbcrlf from buffer.

What don't you try doing Receive(2) if DataReady property is >0 (after WaitFor) in order to consume another 2 characters (\r\n), but you can ignore those (just not use them).

You can even use Peek method to do same as Receive, but just to check what those 2 characters are, since Peek doesn't remove buffer contents. If they are \r\n then call Receive.

Would that help?

Regards,
Damba

Re: Buffer Size Command Hanging

by mmorton, Wednesday, July 08, 2009, 12:54 (5618 days ago) @ wodDamir

No this just gives error messages for different reasons.

This isnt really solution but a workaround which just causes other problems which I cant work out a logical way round it.

Surely the regex expression should return the same result as a normal WaitFor expression without regex.

Example
[code]
sshConnection.Execute( show * /identifier & vbCrLf, regex: & vbCrLf, 30)
sshConnection.Execute( show * /identifier & vbCrLf, vbCrLf, 30)
[/code]

These are the same commands and should produce the same output/desired effect.

Command 1 - In the buffer it now looks like this rn....data
Command 2 - In the buffer it now looks like this ....data

Isnt the regex expression meant to produce the same results?

Re: Buffer Size Command Hanging

by wodSupport, Wednesday, July 08, 2009, 13:13 (5618 days ago) @ mmorton

Hi. Actually, regex Waitfor doesn't return same result as nonregex. Since nonregex is static, it will consume search pattern - since you know exactly what it is.

On the other hand, regex pattern is not consumed and allows you to inspect it to see what to do with it.

Regards,
Kreso

Re: Buffer Size Command Hanging

by mmorton, Wednesday, July 08, 2009, 13:17 (5618 days ago) @ wodSupport

Ok, so how can you retrieve large amounts of data wihtout using Execute while also ensuring all data is there before finishing?

Re: Buffer Size Command Hanging

by wodSupport, Wednesday, July 08, 2009, 13:21 (5618 days ago) @ mmorton

Here's how I would do it. Using send method send the command, and then call Receive or even better ReceiveLine to consume the data.

As data arrives, check if it contains the needed pattern. This is easy to do, except you have to prepare for possibility that data arrives byte by byte, so you always have to search previously received data too.

I suggest it's always good to store last received line. This is small amount of data to search, and can easily be handled using ReceiveLine method.

I can't make this as general approach because search patterns can contain more than one line. You can, however, since you know you only need one line of data for the search.

Does this help?

Kreso

Re: Buffer Size Command Hanging

by mmorton, Wednesday, July 08, 2009, 13:24 (5618 days ago) @ wodSupport

This doesnt work as I have previously said.

If I use RecieveLine etc I only get some of the results. Sometimes I even get no results.

I cant beleive that you provide any sample code for dealing with large amounts of data.

Re: Buffer Size Command Hanging

by wodSupport, Wednesday, July 08, 2009, 13:28 (5618 days ago) @ mmorton

ReceiveLine provies data received until that moment. Did Received event fire later on again?

I am not sure what kind of sample you expect, that is different than current data. wodSSH cannot know how data arrives since this isn't structured protocol at all - data arrives as result of your command, and can be virtually anything.

Speed of arrival doesn't depend on wodSSH. Amoutn doesn't depend either. When *something* arrives, Received event fires so you can call Receive to consume the data.

I'll tell techsupport to create example for you without Waitfor, but it's basically what I just described above.

Kreso

Re: Buffer Size Command Hanging

by mmorton, Wednesday, July 08, 2009, 13:35 (5618 days ago) @ wodSupport

I am running the code purely in a module within a Service.

No event is fired as I am not using a windows form and managing using withevents.

For instance if I run the following code.

[code]
sshConnection.Blocking = False
sshConnection.Send( show * /identifier & vbCrLf)
While sshConnection.DataReady
Dim line_data As String = sshConnection.ReceiveLine()
If line_data.Contains( [ ) And line_data.Contains( ] ) Then passwd.Add(line_data.Replace( , ))
End While
[/code]

This returns no data as the server doesnt send the data in time and the command obviously doesnt wait. If I initially step into this code and then run it, it returns around 2000 records because it doesnt wait for the server to send the next.


The way to solve this was to use Execute and waitfor UAF> but I cant do this because it doesnt work with large amounts of data.

So I can only really gather that the tool cannot cope with large amounts of data becuase of how it works.

Re: Buffer Size Command Hanging

by wodSupport, Wednesday, July 08, 2009, 14:04 (5618 days ago) @ mmorton

Hold on, I'll write a sample. Your

while ssh.dataready

is bad because if data arrives slow then this while will fail. You should call

do
a = ssh.receive
...
while prompt_not_found

when there's no data, ssh.receive will wait for more data, and your loop will run as long as prompt arrives.

Kreso

Re: Buffer Size Command Hanging

by mmorton, Wednesday, July 08, 2009, 14:57 (5618 days ago) @ wodSupport

I have managed to write some code based on what you suggested and it works.

[code]
sshConnection.Blocking = False
sshConnection.Send( show * /identifier & vbCrLf)
Dim data_retrieved As New System.Text.StringBuilder
Do
data_retrieved.Append(sshConnection.Receive().Replace( , ))
Loop While Not data_retrieved.ToString.EndsWith( UAF> )
[/code]

Re: Buffer Size Command Hanging

by wodSupport, Wednesday, July 08, 2009, 15:10 (5618 days ago) @ mmorton

Excellent! Here's mine too in case someone else follows this thread. It takes same time as in ActiveX: [code] static void Main(string[] args)
{
WeOnlyDo.Client.SSH ssh = new WeOnlyDo.Client.SSH();
ssh.Hostname = ******** ;
ssh.Login = ******** ;
ssh.Password = ******** ;
ssh.Blocking = true;
ssh.Connect();

String prompt = kreso@linux ;

// wait for initial prompt
ssh.WaitFor(prompt);
ssh.DataReady = 0;

// send command
ssh.Send( ls -alR /usr
);

String lastline = String.Empty; // this is only thing to test
String totaldata = String.Empty; // this is all between the command and prompt
int i;
do
{
lastline += ssh.Receive();

// remove all lines to buffer
do
{
i = lastline.LastIndexOf('
');
if (i >= 0)
{
totaldata += lastline.Substring(0, i+1);
lastline = lastline.Substring(i + 1);
}
} while (i >= 0);

// check lastline for prompt
i = lastline.IndexOf(prompt);
if (i >= 0)
{
// add existing data to totaldata
totaldata += lastline.Substring(0, i);
lastline = lastline.Substring(i + 1);
break;
}
} while (true);

Console.WriteLine(totaldata);
}
}
[/code]