Trapping for error and displaying receive buffer a - WeOnlyDo Discussion board

Trapping for error and displaying receive buffer a (wodSSH / wodSSH.NET)

by Eric, Friday, December 07, 2007, 14:32 (5957 days ago)

[size=2]Problem:[/size]

Issue 1:
I would like to know how to display what was received after a Prompt times out. One of my Telnet1.Prompt is waiting for some text and times out because it does not find the string I am expecting. When I strip the ANSI from the stream I realize that I loose some of the characters and I need to know what was actually received.

Issue 2:
Also I know that the Prompt function removes the Searched for string out of the stream received. Is there also a way to wait for the string and not remove the string from the stream?

Re: Trapping for error and displaying receive buff

by wodDamir, Friday, December 07, 2007, 15:32 (5957 days ago) @ Eric

Eric,

You are using blocking mode?

In non-blocking mode everything that is received is shown in DataReceived Event.

In blocking mode, you can simply ignore the error, and call Receive method. It will still give you the contents of the buffer.

As for the second question, try using regular expressions like regex:[$ #>] $ for Prompt property. Or, if you know the exact pattern, simply append it to received string.

Regards,
Damba

Re: Trapping for error and displaying receive buff

by Eric, Friday, December 07, 2007, 16:12 (5957 days ago) @ wodDamir

I am using blocking method.

When I use the Prompt method the PromptReceived Event gets called. Here is my Routine:

[code]
Private Sub Telnet1_PromptReceived() Handles Telnet1.PromptReceived
Select Case ExecCount
Case 0
Telnet1.Prompt = Select:
Telnet1.Send( T & vbLf)
Case 1
Telnet1.Prompt = (c)Eagle Con&Dev
Telnet1.Send( e51 & vbLf)
Case 2
Telnet1.Prompt = Login User Name?
Telnet1.Send(vbCrLf)
Case 3
Telnet1.Prompt = Login Password?
Telnet1.Send( s51 & vbLf)
Case 4
Telnet1.Prompt = Login Site?
Telnet1.Send( s51eagle & vbLf)
Case 5
Telnet1.Prompt = Select or E?
Telnet1.Send( 51 & vbLf)
Case 6
Telnet1.Prompt = Select or E?
Telnet1.Send( 3 & vbLf)
Case 7
Telnet1.Prompt = Select or E?
Telnet1.Send( 3 & vbLf)
Case 8
Telnet1.Prompt = Employee Id?
Telnet1.Send( bkn & vbLf)
Case 9
Telnet1.Send( wrkrb & vbLf)
End Select

ExecCount = ExecCount + 1
End Sub
[/code]

My Code fails in Case 3. After the Telnet1.Send( s51 & vbLf) it waits the timeout time and then calls the Dicsonnect Routine by firing the Telnet1.Disconnected event. What is the event for timeout error?

Also I get confused with the Prompt and Send in the above routine. I have to set up the Prompt before the send so that the case works. Is there a better way of doing this? Would the Execute Method be better here?

Re: Trapping for error and displaying receive buff

by woddrazen, Friday, December 07, 2007, 16:37 (5957 days ago) @ Eric

Eric,


Maybe you should switch to WaitFor and Execute Method.

Here is example how to use them:
[code]
Set tel1 = New wodTelnetDLXCom

tel1.HostName = your_hostname
tel1.Blocking = True
tel1.Login = your_login
tel1.Password = your_password
tel1.StripANSI = True
tel1.Connect

tel1.WaitFor ( Select: )
tel1.DataReady = 0
Debug.Print tel1.Execute( T + vbLf, (c)Eagle Con&Dev )
tel1.DataReady = 0
Debug.Print tel1.Execute( e51 + vbLf, Login User Name? )
tel1.DataReady = 0
Debug.Print tel1.Execute( + vbLf, Login Password? )
...
[/code]
If problem persist any chance we could connect to your server and duplicate your issue? You can send your private information to techsupport@weonlydo.com

Let us know how it goes.


Regards,
Drazen

Re: Trapping for error and displaying receive buff

by Eric, Friday, December 07, 2007, 16:46 (5957 days ago) @ woddrazen

I will give it a try with Wait and Execute.

Re: Trapping for error and displaying receive buff

by Eric, Friday, December 07, 2007, 17:25 (5957 days ago) @ Eric

I have no luck with WaitFor and Execute commands. The first Execute times out and does not receive the text looking for. Here is my code:

[code]
Private Sub button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles button1.Click
Telnet1 = New WODTELNETDLXCOMLIB.wodTelnetDLXComClass

Telnet1.Timeout = 30

Telnet1.Hostname = textBox2.Text
Telnet1.Login = textBox3.Text
Telnet1.Password = textBox4.Text
Telnet1.Port = 22
Telnet1.Protocol = WODTELNETDLXCOMLIB.ProtocolsEnum.SSHAuto
Telnet1.Blocking = True
Telnet1.StripANSI = True

Telnet1.Connect()

Telnet1.WaitFor( Select: )
Telnet1.DataReady = 0
Telnet1.Execute( T & vbLf, Select : )
Telnet1.DataReady = 0
Telnet1.Execute( e51 & vbLf, (c)Eagle Con&Dev )
Telnet1.DataReady = 0
Telnet1.Execute(vbCrLf, F4-Exit )
Telnet1.DataReady = 0
Telnet1.Execute( s51 & vbLf, Login Password? )
Telnet1.DataReady = 0
Telnet1.Execute( s51eagle & vbLf, F4-Exit )
Telnet1.DataReady = 0
Telnet1.Execute( 51 & vbLf, Select or E? )
Telnet1.DataReady = 0
Telnet1.Execute( 3 & vbLf, F4-Exit )
Telnet1.DataReady = 0
Telnet1.Execute( 3 & vbLf, Select or E? )
Telnet1.DataReady = 0
Telnet1.Execute( bkn & vbLf, F4-Exit )
Telnet1.DataReady = 0
Telnet1.Execute( wrkrb & vbLf, F4-Exit )
End Sub
[/code]

I was able to get further with Prompt method as listed above. This current way is cleaner from a coding point of view and would be nice to get working.

Re: Trapping for error and displaying receive buff

by woddrazen, Friday, December 07, 2007, 17:30 (5957 days ago) @ Eric

Eric,


Any chance we can connect to your server? That would help us a lot in resolving your issue.


Drazen

Re: Trapping for error and displaying receive buff

by Eric, Friday, December 07, 2007, 17:45 (5957 days ago) @ woddrazen

The server is on an internal firewalled site that is not accessible from outside the company. Sorry about this. I will try some more debugging and see what I can find out.

Re: Trapping for error and displaying receive buff

by Eric, Friday, December 07, 2007, 19:22 (5957 days ago) @ Eric

I have now added an error routine and display the error number. The number is 1460 upon each Execute. What is this number and how do I work around it?

[code]
Private Sub button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles button1.Click
Telnet1 = New WODTELNETDLXCOMLIB.wodTelnetDLXComClass

Telnet1.Timeout = 4

Telnet1.Hostname = textBox2.Text
Telnet1.Login = textBox3.Text
Telnet1.Password = textBox4.Text
Telnet1.Protocol = WODTELNETDLXCOMLIB.ProtocolsEnum.SSHAuto
Telnet1.Port = 22
Telnet1.Blocking = True
Telnet1.StripANSI = True

Telnet1.Connect()

On Error GoTo ErrorHandler
Telnet1.WaitFor( Select: )
Telnet1.DataReady = 0
Telnet1.Execute( T & vbLf, Select : )
Telnet1.DataReady = 0
Telnet1.Execute( e51 & vbLf, (c)Eagle Con&Dev )
Telnet1.DataReady = 0
Telnet1.Execute(vbCrLf, F4-Exit )
Telnet1.DataReady = 0
Telnet1.Execute( s51 & vbLf, Login Password? )
Telnet1.DataReady = 0
Telnet1.Execute( s51eagle & vbLf, F4-Exit )
Telnet1.DataReady = 0
Telnet1.Execute( 51 & vbLf, Select or E? )
Telnet1.DataReady = 0
Telnet1.Execute( 3 & vbLf, F4-Exit )
Telnet1.DataReady = 0
Telnet1.Execute( 3 & vbLf, Select or E? )
Telnet1.DataReady = 0
Telnet1.Execute( bkn & vbLf, F4-Exit )
Telnet1.DataReady = 0
Telnet1.Execute( wrkrb & vbLf, F4-Exit )
Exit Sub

ErrorHandler:
AddToList( Error: & Err.Number & vbLf)
Resume Next
End Sub
[/code]

Re: Trapping for error and displaying receive buff

by woddrazen, Friday, December 07, 2007, 19:26 (5957 days ago) @ Eric

Eric,


You are receiving timeout error. Which line produce such error?


Drazen

Re: Trapping for error and displaying receive buff

by Eric, Friday, December 07, 2007, 19:32 (5957 days ago) @ woddrazen

I get this error at each Execute Statement. It first starts at

[code]
Telnet1.Execute( T & vbLf, Select : )
[/code]

Does the

[code]
Telnet1.DataReady = 0
[/code]

have anything to do with this? It seams as though the string is not received. When I used the prompt method posted above I was able to traverse though the menus.

Re: Trapping for error and displaying receive buff

by woddrazen, Friday, December 07, 2007, 19:39 (5957 days ago) @ Eric

Eric,


I think you should change your code little bit. First need to wait for Select: prompt. After Select: is received you need to send T and you are waiting for (c)Eagle Con&Dev prompt.

In your code after T you are waiting again for Select: prompt and I'm not sure this is what you want.

[code]
tel1.WaitFor ( Select: )
tel1.DataReady = 0
Debug.Print tel1.Execute( T + vbLf, (c)Eagle Con&Dev )
tel1.DataReady = 0
Debug.Print tel1.Execute( e51 + vbLf, Login User Name? )
[/code]

Drazen

Re: Trapping for error and displaying receive buff

by Eric, Friday, December 07, 2007, 19:52 (5957 days ago) @ woddrazen

There are two Select: prompts.

Here is the 1st screen. Send T to go to next Screen

_____________________________________________
Welcome to the DEV1
eB2 Development Menu
Fri Dec 7 13:43:35 EST 2007
- - - - - - - - - - - - - - - - - - -
B. Barcoding Menu
D. Development and Test QAD Database Menu
E. Eagle Menu
O. QAD Database Menu
R. Development Results Menu
T. Training QAD and Eagle Database Menu
- - - - - - - - - - - - - - - - - - -
P. Password Change (UNIX)
X. Log Off System
- - - - - - - - - - - - - - - - - - -
p5104 - Select:
_____________________________________________


Here is the 2nd screen. Send e51 to go to next Screen
_____________________________________________
Welcome to the DEV1
eB2 Test Menu
Fri Dec 7 13:46:41 EST 2007
- - - - - - - - - - - - - - - - - - -
50. TRAINING QAD e50. Eagle
- - - - - - - - - - - - - - - - - - -
b. Back to the Main Menu
x. Log Off System
- - - - - - - - - - - - - - - - - - -
p5104 - Select:
_____________________________________________


Here is the 3rd screen. Need to send Enter

_____________________________________________
Company:
TRAINING
DB: qaddb
(c)Eagle Con&Dev

_____________________________________________


Here is the 4th screen. Need to send 51
_____________________________________________
[MFGPRO LOGIN]
Login User Name?
P5104


_____________________________________________

F1-Go F4-Exit


These are just the first few screens that need to be automated. I hope this gives you an idea what I am trying to do.

Re: Trapping for error and displaying receive buff

by woddrazen, Friday, December 07, 2007, 20:06 (5957 days ago) @ Eric

Eric,


What happened if you change:

Select:

with:

p5104 - Select:

or

p5104 - Select:

or

regex:[\$ #>] $


Drazen

Re: Trapping for error and displaying receive buff

by Eric, Friday, December 07, 2007, 20:29 (5957 days ago) @ woddrazen

Same issue happens. Can You please explain what is happening here:

[code]
Telnet1.Connect()

On Error GoTo ErrorHandler
Telnet1.WaitFor( p5104 - Select: )
Telnet1.DataReady = 0
Telnet1.Execute( T & vbLf, p5104 - Select: )
[/code]

Lines:
1 - Connect to host
2 - On Error call special Handler
3 - Receive the output from the host and wait for string p5104 - Select:
4 - Turn off receive buffer for next command
5 - Send T to host and receive output to buffer and wait for string p5104 - Select:

[size=2]Prompt Method[/size]
[code]
Private Sub button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles button1.Click
.
.
.
Telnet1.Prompt = p5104 - Select:

ExecCount = 0
Telnet1.Connect()
End Sub

Private Sub Telnet1_PromptReceived() Handles Telnet1.PromptReceived
Select Case ExecCount
Case 0
AddToList(Telnet1.Prompt)
Telnet1.Prompt = p5104 - Select:
Telnet1.Send( T & vbLf)
Case 1
AddToList(Telnet1.Prompt)
Telnet1.Prompt = (c)Eagle Con&Dev
Telnet1.Send( e51 & vbLf)
Case 2
.
.
.
End Select

ExecCount = ExecCount + 1
End Sub
[/code]

Here the prompt is defined before the Connect method. This way the output buffer is scaned for the string p5104 - Select: . When the string is found it raises the Telnet1.PromptReceived Event which is then handled by the case statement above.

Is there a difference of when the buffer is received and lost with the WaitFor and Execute method? What I mean is that the only time a Timeout event can be raised if it does not find the string in the received buffer. This is turned off for WiatFor and Execute so where is the buffer to read the data stream?

Re: Trapping for error and displaying receive buff

by Eric, Friday, December 07, 2007, 21:18 (5957 days ago) @ Eric

I found out something interesting with the Execute command.

[code]
Telnet1.WaitFor( p5104 - Select: )
Telnet1.DataReady = 0
Telnet1.Execute( T & vbCrLf, Select )
Telnet1.DataReady = 0
Telnet1.Execute( e51 & vbCrLf, Dev )
Telnet1.DataReady = 0
Telnet1.Execute( & vbCrLf, p5104 )
Telnet1.DataReady = 0
Telnet1.Execute( s51 & vbCrLf, Login )
Telnet1.DataReady = 0
[/code]

Works, the Execute does not like any specail characters (space, or other) When I strip these out I am able to traverse the script. Is this becuse stripANSI removes them? I believe that I am battling some wierdness here. After the 4th Execute statement there is another error fired 10054 - The current socket connection has been reset. I am happy that i am able to get the code working this far but I really do need to complete all of the menus (10 in total)

Re: Trapping for error and displaying receive buff

by woddrazen, Friday, December 07, 2007, 22:03 (5957 days ago) @ Eric

Eric,


It's hard to say what's wrong without duplicate it. You can try to find what in received in wodTelenetDLX using Receive Method and send that as next Prompt.

Here is example:
[code]
Telnet1.Execute( & vbCrLf, p5104 )
Telnet1.Send( s51 & vbCrLf)
Debug.Print Telnet1.Receive
Debug.Print Telnet1.Receive
Debug.Print Telnet1.Receive
[/code]

or maybe you can try without Execute Method. Using WaitFor and Send Method. Just like you use Prompt Property and Send Method.

Here is example:
[code]
Telnet1.WaitFor( Select: )
Telnet1.Send( T & vbLf)
Telnet1.WaitFor( (c)Eagle Con&Dev )
Telnet1.Send( e51 & vbLf)
Telnet1.WaitFor( Login User Name? )
Telnet1.Send(vbCrLf)
Telnet1.WaitFor( Login Password? )
Telnet1.Send( s51 & vbLf)
Debug.Print Telnet1.Receive
Debug.Print Telnet1.Receive
Debug.Print Telnet1.Receive
[/code]


Drazen

Re: Trapping for error and displaying receive buff

by Eric, Friday, December 07, 2007, 22:18 (5957 days ago) @ woddrazen

I will try the WaitFor and Send method.

Question: What is the purpose of

Debug.Print Telnet1.Receive
Debug.Print Telnet1.Receive
Debug.Print Telnet1.Receive

Would not this be better:

Telnet1.Receive(Telnet1.DataReady) - to receive all pending info from buffer?

Re: Trapping for error and displaying receive buff

by woddrazen, Friday, December 07, 2007, 22:37 (5957 days ago) @ Eric

Eric,


Telnet1.Receive(Telnet1.DataReady) and Telnet1.Receive is more or less same.

In both cases amount of data that arrived from server is received using Receive Method but mostly this isn't all that is received by server.

SSH connection is ongoing connection between client and server.

That's why you need to use more then one Receive Method to be sure that you receive all from server.


Drazen

Re: Trapping for error and displaying receive buff

by Eric, Monday, December 10, 2007, 14:55 (5954 days ago) @ woddrazen

[size=2]Success[/size]

I wanted to update this post as I have found a solution using the prompte method.

[code]
Private Sub button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles button1.Click

Telnet1 = New WODTELNETDLXCOMLIB.wodTelnetDLXComClass
Telnet1.Timeout = 4
Telnet1.Hostname = textBox2.Text
Telnet1.Login = textBox3.Text
Telnet1.Password = textBox4.Text
Telnet1.Protocol = WODTELNETDLXCOMLIB.ProtocolsEnum.Telnet
'Telnet1.Port = 22
Telnet1.Blocking = 1
Telnet1.StripANSI = True

Telnet1.Prompt = p5104 - Select:
ExecCount = 0

Telnet1.Connect()
End Sub

Private Sub AddToList(ByVal Text As String)
textBox1.AppendText(Text)
End Sub

Private Sub Telnet1_Connected(ByVal ErrorCode As Short, ByVal ErrorText As String) Handles Telnet1.Connected
If ErrorCode <> 0 Then
AddToList( CONNECT error: & ErrorText & vbCrLf)
Else
AddToList( CONNECTED! & vbCrLf)
End If
End Sub
Private Sub Telnet1_Disconnected() Handles Telnet1.Disconnected
AddToList( DISCONNECTED & vbCrLf)
End Sub

Private Sub Telnet1_PromptReceived() Handles Telnet1.PromptReceived
Select Case ExecCount
Case 0
AddToList(Telnet1.Prompt)
Telnet1.Prompt = p5104 - Select:
Telnet1.Send( T & vbCrLf)
Case 1
AddToList(Telnet1.Prompt)
Telnet1.Prompt = Dev
Telnet1.Send( e51 & vbCrLf)
Case 2
AddToList(Telnet1.Prompt)
Telnet1.Prompt = Exit
Telnet1.Send(vbCrLf)
Case 3
AddToList(Telnet1.Prompt)
Telnet1.Prompt = Password
Telnet1.Send( s51 & vbCrLf)
Case 4
AddToList(Telnet1.Prompt)
Telnet1.Prompt = Exit
Telnet1.Send( s51eagle & vbCrLf)
Case 5
AddToList(Telnet1.Prompt)
Telnet1.Prompt = Select
Telnet1.Send( 51 & vbCrLf)
Case 6
AddToList(Telnet1.Prompt)
Telnet1.Prompt = Select
Telnet1.Send( 3 & vbCrLf)
Case 7
AddToList(Telnet1.Prompt)
Telnet1.Prompt = Select
Telnet1.Send( 3 & vbCrLf)
Case 8
AddToList(Telnet1.Prompt)
Telnet1.Prompt = Employee
Telnet1.Send( bkn & vbCrLf)
Case 9
AddToList(Telnet1.Prompt)
Telnet1.Send( wrkrb & vbCrLf)
End Select

ExecCount = ExecCount + 1
End Sub

Private Sub Telnet1_Received(ByVal ByteCount As Short) Handles Telnet1.Received
Dim a As String

a = Telnet1.Receive(ByteCount, 0)
AddToList(a)
End Sub

[/code]

[size=2]Problems Found with Resolutions[/size]
Problem 1: ANSI Characters were causing the prompts to fail
Resolution 1:used strip ANSI to resolve issue
Problem 2: SSHAuto would not let script complete due to some characters not encoding properly
Resolution 2:Converted to Telnet Protocol
Problem 3: Sent data was not always working with menus
Resolution 3:Made sure all send data appended vbCrLf rather than vbLf

Re: Trapping for error and displaying receive buff

by woddrazen, Monday, December 10, 2007, 15:09 (5954 days ago) @ Eric

Eric,


Excellent! I'm happy to hear that issue is solved now.

Also I would like to thank you for sharing your solution with us.


Drazen

Re: Trapping for error and displaying receive buff

by Eric, Monday, December 10, 2007, 15:21 (5954 days ago) @ woddrazen

I am glad to share. Helping each other is definately a quicker approach to problem solving.

Regards,
Eric

Re: Trapping for error and displaying receive buff

by Eric, Monday, December 10, 2007, 16:05 (5954 days ago) @ Eric

[size=2]Method 2 - Cleaner Code with WaitFor command[/size]

I have reworked the script to work with WiatFor commands. This is a little cleaner code as it allows you to follow the coding better.

Prompt commands need to be defined first before the Send command. This means that you have to define the text desired to be received before the command to answer the current screen. This can get confusing and you have to make sure you debug often. The reason is that this method requires a PromptReceived event handler to be set up to trap for the prompt events and then you also need a counter to make sure you get to the proper itteration code to hadle the event. This is a little more difficult to follow than the WaitFor method.


WaitFor commands are great as you can itterate through the code directly. You do not need an event handler because the program pauses and waites for the desired string to be found. Once the string is found the program continues with the next line of code . Ths only thing to remember here is that there is a timeout that you will have to account for to handle the errors properly or else your code will fail inadvertantly.

Solution:
[code]
Private Sub button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles button1.Click
Dim myError As System.Exception

Telnet1 = New WODTELNETDLXCOMLIB.wodTelnetDLXComClass

Telnet1.Timeout = 4

Telnet1.Hostname = textBox2.Text
Telnet1.Login = textBox3.Text
Telnet1.Password = textBox4.Text
Telnet1.Protocol = WODTELNETDLXCOMLIB.ProtocolsEnum.Telnet
Telnet1.Blocking = 1
Telnet1.StripANSI = True

Telnet1.Connect()

On Error GoTo ErrorHandler
Telnet1.WaitFor( p5104 - Select: )
AddToList( Menu 1: T - Training QAD and Eagle Database Menu & vbCrLf)
Telnet1.Send( T & vbLf)
Telnet1.WaitFor( p5104 - Select: )
AddToList( Menu 2: e51 - Eagle & vbCrLf)
Telnet1.Send( e51 & vbCrLf)
Telnet1.WaitFor( Dev )
AddToList( Menu 3: CrLf - Eagle Header Screen & vbCrLf)
Telnet1.Send(vbCrLf)
Telnet1.WaitFor( Exit )
AddToList( Menu 4: s51 - Login User Name? & vbCrLf)
Telnet1.Send( s51 & vbCrLf)
Telnet1.WaitFor( Password )
AddToList( Menu 5: s51eagle - Login Password? & vbCrLf)
Telnet1.Send( s51eagle & vbCrLf)
Telnet1.WaitFor( Exit )
AddToList( Menu 6: 51 - Login Site? & vbCrLf)
Telnet1.Send( 51 & vbCrLf)
Telnet1.WaitFor( Select )
AddToList( Menu 7: 3 - Prod Menu......3 & vbCrLf)
Telnet1.Send( 3 & vbCrLf)
Telnet1.WaitFor( Select )
AddToList( Menu 8: 3 - Rep Menu 1.....3 & vbCrLf)
Telnet1.Send( 3 & vbCrLf)
Telnet1.WaitFor( Select )
AddToList( Menu 9: bkn - Kanban BKF...BKN & vbCrLf)
Telnet1.Send( bkn & vbCrLf)
Telnet1.WaitFor( Employee )
AddToList( Menu 10: wrkrb - Employee Id? & vbCrLf)
Telnet1.Send( wrkrb & vbCrLf)

Exit Sub

ErrorHandler:
AddToList( Error: & Err.Number & vbLf)
AddToList(Err.Source & vbLf)
' Assigns the exception from the Err object to myError.
myError = Err.GetException()
' Displays the message associated with the exception.
AddToList(myError.Message & vbLf)

Resume Next
End Sub
[/code]

I hope this helps others in how these commands work together.

Regards,
Eric