Find below the source code for this project in case someone needs to modify it to meet their needs. It was coded in MS Visual Basic 2008 Express Edition. Don't forget to add a reference to HBDotNet. Many thanks to allanstevens for posting his source code for the weather.com plugin.
Code: Select all
Imports System
Imports System.Collections.Generic
Imports System.Text
Imports HBDotNet
Imports System.Net
Imports System.IO
Imports System.Net.Sockets
Namespace TCPClient
<HBDevice("TCP Client")> _
Public Class TCPClient
Inherits HBDeviceBase
Public Event onConnect()
Public Event onerror(ByVal Description As String)
Public Event onDataArrival(ByVal Data As String, ByVal TotalBytes As Integer)
Public Event onDisconnect()
Public Event onSendComplete(ByVal DataSize As Integer)
Private Shared response As [String] = [String].Empty
Private Shared port As Integer = 44
Private Shared ipHostInfo As IPHostEntry = Dns.GetHostEntry("localhost")
Private Shared ipAddress As IPAddress = ipHostInfo.AddressList(0)
Private Shared client As New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
Private Shared MyBuffer As New StringBuilder
Public Overloads Overrides Function OnInit(ByVal enabled As Boolean) As Boolean
If enabled Then
enabled = OnEnable()
End If
MyBase.OnInit(enabled)
Return True
End Function
Public Overloads Overrides Sub OnShutdown()
Try
client.Shutdown(SocketShutdown.Both)
Catch
End Try
client.Close()
MyBase.OnShutdown()
End Sub
Public Overloads Overrides Function OnEnable() As Boolean
If Me.Connected = False Then
If GetProperty("TCConnected") = "1" Then
If GetProperty("TCHostAddress") <> "<ENTER IP ADDRESS>" And GetProperty("TCHostPort") <> "<ENTER PORT NUMBER>" Then
Me.EstablishConnection(GetProperty("TCHostAddress"), CInt(GetProperty("TCHostPort")))
End If
End If
End If
Return True
End Function
Public Overloads Overrides Function OnDisable() As Boolean
If Me.Connected = True Then
Me.BreakConnection()
End If
Return MyBase.OnDisable()
End Function
Public Overloads Overrides Sub OnAboutBox()
MsgBox("This plugin is used to send and receive data from a TCP server.")
End Sub
Protected Overloads Overrides Function OnPropertyChangeRequest(ByVal hbProperty As HBDotNet.HBProperty, ByVal newValue As String) As Boolean
HBModule.TraceDeviceMessage(_deviceHandle, TRC_TYPE.ttDebug, hbProperty.Name & " changed to " & newValue)
If Me.Connected() = True Then
If hbProperty.Name = "TCSendData" And newValue <> "" Then
Me.SendData(newValue & vbCr)
End If
If hbProperty.Name = "TCHostAddress" Or hbProperty.Name = "TCHostPort" Then
Me.BreakConnection()
End If
If hbProperty.Name = "TCConnected" And newValue = "0" Then
Me.BreakConnection()
End If
Else
If hbProperty.Name = "TCConnected" And newValue = "1" Then
If GetProperty("TCHostAddress") <> "<ENTER IP ADDRESS>" And GetProperty("TCHostPort") <> "<ENTER PORT NUMBER>" Then
Me.EstablishConnection(GetProperty("TCHostAddress"), CInt(GetProperty("TCHostPort")))
Else
HBModule.TraceDeviceMessage(_deviceHandle, TRC_TYPE.ttError, "IP address or port are not valid.")
End If
End If
End If
Return MyBase.OnPropertyChangeRequest(hbProperty, newValue)
End Function
Public Overloads Overrides Function OnRegisterProperties() As Boolean
Properties.Add(New HBProperty("TCHostAddress", "TCHostAddress", False, "<ENTER IP ADDRESS>", eIOType.ioOutputOnly, True, _
True, True, False, ePropertyType.ptAlpha, ""))
Properties.Add(New HBProperty("TCHostPort", "TCHostPort", False, "<ENTER PORT NUMBER>", eIOType.ioOutputOnly, True, _
True, True, False, ePropertyType.ptAlpha, ""))
Properties.Add(New HBProperty("TCConnected", "TCConnected", True, "0", eIOType.ioInputAndOutput, True, _
True, True, False, ePropertyType.ptBoolean, ""))
Properties.Add(New HBProperty("TCClear", "TCClear", False, "0", eIOType.ioInputAndOutput, True, _
True, True, False, ePropertyType.ptBoolean, ""))
Properties.Add(New HBProperty("TCReceivedData", "TCReceivedData", False, "", eIOType.ioInputOnly, True, _
True, True, False, ePropertyType.ptAlpha, ""))
Properties.Add(New HBProperty("TCSendData", "TCSendData", False, "", eIOType.ioOutputOnly, True, _
True, True, False, ePropertyType.ptAlpha, ""))
Return MyBase.OnRegisterProperties()
End Function
Public Sub SetProperty(ByVal propertyName As String, ByVal propertyValue As String)
Properties.GetPropertyByName(propertyName).CurrentValue = propertyValue
End Sub
Public Sub SetProperty(ByVal propertyName As String, ByVal propertyValue As Double)
Properties.GetPropertyByName(propertyName).CurrentValue = propertyValue.ToString()
End Sub
Public Sub SetProperty(ByVal propertyName As String, ByVal propertyValue As Double, ByVal decimalPrecision As Integer)
Properties.GetPropertyByName(propertyName).CurrentValue = propertyValue.ToString("F" & decimalPrecision.ToString())
End Sub
Public Function GetProperty(ByVal propertyName As String) As String
Return Properties.GetPropertyByName(propertyName).CurrentValue
End Function
Private Sub EstablishConnection(ByVal RemoteHostName As String, ByVal RemotePort As Integer)
Try
client = New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
port = RemotePort
ipHostInfo = Dns.GetHostEntry(RemoteHostName)
ipAddress = ipHostInfo.AddressList(0)
Dim remoteEP As New IPEndPoint(ipAddress, port)
client.BeginConnect(remoteEP, AddressOf sockConnected, client)
HBModule.TraceDeviceMessage(_deviceHandle, TRC_TYPE.ttDebug, "Attempting connection to " & RemoteHostName & ":" & RemotePort.ToString & ".")
Catch
RaiseEvent onerror(Err.Description)
Exit Sub
End Try
End Sub
Private Sub SendData(ByVal Data As String)
Try
Dim byteData As Byte() = ASCIIEncoding.ASCII.GetBytes(Data)
client.BeginSend(byteData, 0, byteData.Length, 0, AddressOf sockSendEnd, client)
HBModule.TraceDeviceMessage(_deviceHandle, TRC_TYPE.ttDebug, "Sending data (" & Data & ").")
Catch
RaiseEvent onerror(Err.Description)
Exit Sub
End Try
End Sub
Private Sub BreakConnection()
Try
client.Shutdown(SocketShutdown.Both)
HBModule.TraceDeviceMessage(_deviceHandle, TRC_TYPE.ttDebug, "Socket shutting down.")
Catch
HBModule.TraceDeviceMessage(_deviceHandle, TRC_TYPE.ttDebug, "There was a problem shutting down the socket.")
End Try
End Sub
Private Sub sockConnected(ByVal ar As IAsyncResult)
Try
If client.Connected = False Then RaiseEvent onerror("Connection refused.") : Exit Sub
Dim state As New StateObject
state.workSocket = client
client.BeginReceive(state.buffer, 0, state.BufferSize, 0, AddressOf sockDataArrival, state)
RaiseEvent onConnect()
Catch
RaiseEvent onerror(Err.Description)
Exit Sub
End Try
End Sub
Private Sub sockDataArrival(ByVal ar As IAsyncResult)
Dim state As StateObject = CType(ar.AsyncState, StateObject)
Dim client As Socket = state.workSocket
Dim ReuseSocket As Boolean = True
Dim bytesRead As Integer
Try
bytesRead = client.EndReceive(ar)
Catch
Exit Sub
End Try
System.Threading.Thread.CurrentThread.Sleep(500)
Try
Dim Data() As Byte = state.buffer
If bytesRead = 0 Then
client.Disconnect(True)
HBModule.TraceDeviceMessage(_deviceHandle, TRC_TYPE.ttDebug, "Socket closing.")
RaiseEvent onDisconnect()
Exit Sub
End If
ReDim state.buffer(32767)
client.BeginReceive(state.buffer, 0, state.BufferSize, 0, AddressOf sockDataArrival, state)
RaiseEvent onDataArrival(Replace(Replace(Replace(ASCIIEncoding.ASCII.GetString(Data), Chr(3), "<ETX>" & Chr(149)), Chr(2), "<STX>"), Chr(0), ""), bytesRead)
Catch
RaiseEvent onerror(Err.Description)
Exit Sub
End Try
End Sub
Private Sub sockSendEnd(ByVal ar As IAsyncResult)
Try
Dim client As Socket = CType(ar.AsyncState, Socket)
Dim bytesSent As Integer = client.EndSend(ar)
RaiseEvent onSendComplete(bytesSent)
Catch
RaiseEvent onerror(Err.Description)
Exit Sub
End Try
End Sub
Private Function Connected() As Boolean
Try
Return client.Connected
Catch
RaiseEvent onerror(Err.Description)
Exit Function
End Try
End Function
Private Sub ClearBuffer()
Dim MyBufferLength As Integer = MyBuffer.Length
MyBuffer.Remove(0, MyBufferLength)
Me.SetProperty("TCClear", "0")
End Sub
Private Sub TCPSocket_onConnect() Handles Me.onConnect
HBModule.TraceDeviceMessage(_deviceHandle, TRC_TYPE.ttDebug, "Connection established.")
End Sub
Private Sub TCPSocket_onDataArrival(ByVal Data As String, ByVal TotalBytes As Integer) Handles Me.onDataArrival
HBModule.TraceDeviceMessage(_deviceHandle, TRC_TYPE.ttDebug, "Data (" & Data & ") arrived.")
If Me.GetProperty("TCClear") = "1" Then
Me.ClearBuffer()
End If
MyBuffer.Append(Data)
Me.SetProperty("TCReceivedData", MyBuffer.ToString)
End Sub
Private Sub TCPSocket_onDisconnect() Handles Me.onDisconnect
Me.SetProperty("TCConnected", "0")
Me.ClearBuffer()
HBModule.TraceDeviceMessage(_deviceHandle, TRC_TYPE.ttDebug, "Socket disconnected.")
End Sub
Private Sub TCPSocket_onerror(ByVal Description As String) Handles Me.onerror
HBModule.TraceDeviceMessage(_deviceHandle, TRC_TYPE.ttError, "TCP Socket Error: " & Description)
Err.Clear()
End Sub
Private Sub TCPSocket_onSendComplete(ByVal DataSize As Integer) Handles Me.onSendComplete
Me.SetProperty("TCSendData", "")
HBModule.TraceDeviceMessage(_deviceHandle, TRC_TYPE.ttDebug, "Data sent.")
End Sub
End Class
Public Class StateObject
Public workSocket As Socket = Nothing
Public BufferSize As Integer = 32767
Public buffer(32767) As Byte
Public sb As New StringBuilder()
End Class
End Namespace