Just received a nice email from Eric Lamey, who has written and upgraded version of the telnet client. It warranted its own article, so here is the email it is.
Hello Dominic,
My name is Eric Lamey from Evansville Indiana USA.
Your telnet program helped me a great deal, I fixed some the problems and added a few things. So I wanted to share since you shared. I tried to post it to your comments section twice but it was a mess with html tags ect....so here is the code (below the comments). Thanks again. It's almost impossible to find anything on vb.net and telnetting so I appreciate your sharing!!
'Eric Lamey
'Evansville, IN USA
'elamey@gmx.com
'
'Thank you for your great work. This put me so far ahead that I wanted to share.
'My fixes and updates so I fixed the "bodge" for you, getting rid of the timer & private variable
'The problem was that VB will only let you update the UI, from the UI's (root)thread.
'It's called an IllegalCrossThreadCall
'You can cheat the IllegalCrossThreadCall by placing the following in your first
'sub or function. But don't do it, it's not threadsafe
'CheckForIllegalCrossThreadCalls = False
'If you use this ^^^^^^^^^^ then multiple threads could be updating the UI at the same time, not thread safe.
'There are a few methods to update the main UI from spawned threads but the easiest is to invoke a method.
'In short, you have to
'
'1. Create a Sub that does the work you want....in this case, update the txtResponse text box.
' Private Sub DisplayResult(ByVal result As String)
'
'2. Create a delegate for that Sub
' Private Delegate Sub DisplayResultDelegate(ByVal result As String)
'
'3. Then invoke it from your thread
' Me.Invoke(New DisplayResultDelegate(AddressOf DisplayResult), receivedString)
'
'I also did some other things
' - The buffer was not large enough for my needs so I increased it
' Private Const BYTES_TO_READ As Integer = 4096
' Dim receivedString As String = System.Text.Encoding.UTF8.GetString(readBuffer, 0, BYTES_TO_READ)
' - I cleared out the buffer after invoking the display delegate. This cleans up duplicate text lines
' on multiple send/receive cycles
' Array.Clear(readBuffer, 0, readBuffer.Length)
' - I added a regex to replace all characters except alpha, digit and others (there was a question about that)
' result = Regex.Replace(result, "[^A-Za-z0-9>#:\s]", "", RegexOptions.Compiled)
' - added some timeouts to the client
' client.SendTimeout = 3000
' client.ReceiveTimeout = 3000
' - appended the text in the textbox so I could keep all the text (i'm telnetting a switch)
' txtResponse.AppendText(String.Concat(vbCrLf, result))
' - made frmMain accept button the cmdSend_Click button and put focus back in txtCommand
' box after displaying results so I can type command, hit enter, type command hit enter
' with no mouse clicks
'
'Further needs:
' -Error checking
' -Graceful closing of connection
'
Imports System.Text
Imports System.Text.RegularExpressions
Public Class frmMain
Private client As System.Net.Sockets.TcpClient
Private Const BYTES_TO_READ As Integer = 4096
Private readBuffer(BYTES_TO_READ) As Byte
Private Delegate Sub DisplayResultDelegate(ByVal result As String)
Private Sub DisplayResult(ByVal result As String)
result = Regex.Replace(result, "[^A-Za-z0-9>#:\s]", "", RegexOptions.Compiled)
If Me.InvokeRequired Then
Me.Invoke(New DisplayResultDelegate(AddressOf DisplayResult))
Else
txtResponse.AppendText(String.Concat(vbCrLf, result))
' txtResponse.Text = txtResponse.Text. <<<< ok to remove if you want...reference
End If
txtCommand.Focus()
End Sub
Private Sub SendMessage(ByVal msg As String)
Dim sw As IO.StreamWriter
Try
sw = New IO.StreamWriter(client.GetStream)
sw.Write(msg + vbCrLf)
sw.Flush()
Catch ex As Exception
MessageBox.Show(ex.ToString)
End Try
End Sub
Private Sub doRead(ByVal ar As System.IAsyncResult)
Dim totalRead As Integer
Try
'Ends the reading and returns the number of bytes read.
totalRead = client.GetStream.EndRead(ar)
Catch ex As Exception
'The underlying socket have probably been closed OR an error has occured whilst trying
'to access it, either way, this is where you should remove close all eventuall connections
'to this client and remove it from the list of connected clients.
End Try
If totalRead > 0 Then
'the readBuffer array will contain everything read from the client.
Dim receivedString As String = System.Text.Encoding.UTF8.GetString(readBuffer, 0, BYTES_TO_READ)
'txtResponse.Text = receivedString <<<< ok to remove...just left for reference
Me.Invoke(New DisplayResultDelegate(AddressOf DisplayResult), receivedString)
Array.Clear(readBuffer, 0, readBuffer.Length)
End If
Try
'Begin the reading again.
client.GetStream.BeginRead(readBuffer, 0, BYTES_TO_READ, AddressOf doRead, Nothing)
Catch ex As Exception
'The underlying socket have probably been closed OR an error has occured whilst trying
'to access it, either way, this is where you should remove close all eventuall connections
'to this client and remove it from the list of connected clients.
End Try
End Sub
Private Sub cmdSend_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdSend.Click
txtResponse.AppendText(String.Concat(txtCommand.Text, vbCrLf))
SendMessage(txtCommand.Text)
txtCommand.Text = ""
client.GetStream.BeginRead(readBuffer, 0, BYTES_TO_READ, AddressOf doRead, Nothing)
End Sub
Private Sub cmdConnect_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdConnect.Click
cmdSend.Enabled = True
txtCommand.Enabled = True
txtResponse.Enabled = True
client = New System.Net.Sockets.TcpClient(txtIP.Text, txtPort.Text)
client.SendTimeout = 3000
client.ReceiveTimeout = 3000
client.GetStream.BeginRead(readBuffer, 0, BYTES_TO_READ, AddressOf doRead, Nothing)
End Sub
Private Sub messageReceived(ByVal message As String)
MessageBox.Show(message)
End Sub
End Class
To keep our site free from spam, all comments are moderated prior to publishing. Your comment will be read by one of our staff, and provided it is not blatant advertising, rude or against the spirit of our site, we will do our best to ensure it will appear within one business day. Should you have any specific questions about any item, you should use the Contact page to get in touch instead.