I'm writing a class to encapsulate an udpclient and do a little processing on the messages sent and received.
I think that what i need is something similar to a hook.
Meaning that when the parent class instantiates an object of my custom class, it should provide a callback function to call when a packet is received and processed.
Now I have mainly two doubts:
-should I force the New constructor to ask for a callback and fail without? if so, how do I do it?
-right now I've written a blank sub to trigger the reception of messages, which should accept the callback function as parameter, how should this declaration be constructed?
I hope my doubts are clear, I'm reading about delegates and the likes, but I'm still not very familiar with all these concepts.
The sub i refer to is "StartListening".
Some comments on the code:
the New sub essentially finds the local main ip address and related subnet mask, from those it calculates the sub-network broadcast ip.
StartListening and StopListening should be self explanatory.
ProcessReceive is the internal sub that encapsulates system.net.udpclient doing the hardwork.
SendMessage is the exposed interface to receive the string to send from the parent class.
The rest are service subs and functions.
I think that what i need is something similar to a hook.
Meaning that when the parent class instantiates an object of my custom class, it should provide a callback function to call when a packet is received and processed.
Now I have mainly two doubts:
-should I force the New constructor to ask for a callback and fail without? if so, how do I do it?
-right now I've written a blank sub to trigger the reception of messages, which should accept the callback function as parameter, how should this declaration be constructed?
I hope my doubts are clear, I'm reading about delegates and the likes, but I'm still not very familiar with all these concepts.
VB.NET:
Public Class RemoteSciamiInterface
Private _receive As Boolean
Private _message As String
Private _udpclient As New System.Net.Sockets.UdpClient(12500)
Private _hostname As String = System.Net.Dns.GetHostName
Private _hostaddr As System.Net.IPAddress = System.Net.Dns.GetHostByName(_hostname).AddressList.GetValue(0)
Private _localendpoint As New System.Net.IPEndPoint(0, 0)
Private _destendpoint As New System.Net.IPEndPoint(0, 0)
Private _subnet As New System.Net.IPAddress(0)
Private _receivingaddress As New System.Net.IPEndPoint(System.Net.IPAddress.Any, 0)
Private _enc As New System.Text.ASCIIEncoding
Private regPath As String = "System\CurrentControlSet\Services\Tcpip\Parameters\Interfaces\"
Private registrystart As RegistryKey
Private _mycallback As AsyncCallback
Private _myobj As New Object
Private _local32 As UInteger = GetBinaryAddress(_hostaddr)
Public Sub New()
_mycallback = AddressOf processreceive
registrystart = Registry.LocalMachine.OpenSubKey(regPath, False)
Dim counter As Integer = 0
'Dim subkeys As String() = registrystart.GetSubKeyNames
For Each temp As String In registrystart.GetSubKeyNames
counter = counter + 1
Dim temp2 As RegistryKey = Registry.LocalMachine.OpenSubKey(regPath & temp, False)
Try
If temp2.GetValue("DhcpIPAddress").Equals(_hostaddr.ToString) Then
Net.IPAddress.TryParse(temp2.GetValue("DhcpSubnetMask"), _subnet)
ElseIf temp2.GetValue("IPAddress").Equals(_hostaddr.ToString) Then
Net.IPAddress.TryParse(temp2.GetValue("SubnetMask"), _subnet)
End If
Catch ex As Exception
End Try
Next
Dim _broadcast As Net.IPAddress = GetLocalBroadcast(_hostaddr, _subnet)
_destendpoint.Address = _broadcast
_destendpoint.Port = 12500
_localendpoint.Address = _hostaddr
_localendpoint.Port = 12500
End Sub
Public Sub StartListening()
_udpclient.BeginReceive(_mycallback, _myobj)
_receive = True
End Sub
Public Sub StopListening()
_receive = False
End Sub
Private Sub processreceive(ByVal result As IAsyncResult)
Try
Dim _mystring As String = _enc.GetChars(_udpclient.EndReceive(result, _receivingaddress))
If MessaggeIsForUS(_mystring) Then
End If
Catch ex As Exception
MsgBox(ex)
End Try
If _receive Then
_udpclient.BeginReceive(_mycallback, _myobj)
End If
End Sub
Public Function SendMessage(ByVal mess As String) As Boolean
Dim localmess As String = "SRC=" + _hostaddr.ToString + "," + "DST=" + _destendpoint.Address.ToString + "," + "MSG=" + mess + ",END"
Try
_udpclient.Send(_enc.GetBytes(localmess), _enc.GetByteCount(localmess), _destendpoint)
Return 0
Catch ex As Exception
Return -1
End Try
End Function
Public Function SendMessage(ByVal mess As String, ByVal address As String)
Dim destendpoint As New System.Net.IPEndPoint(address, 0)
Dim localmess As String = "SRC=" + _hostaddr.ToString + "," + "DST=" + address + "," + "MSG=" + mess + ",END"
Try
_udpclient.Send(_enc.GetBytes(localmess), _enc.GetByteCount(localmess), _destendpoint)
Return 0
Catch ex As Exception
Return -1
End Try
End Function
Private Function GetLocalBroadcast(ByVal addr As Net.IPAddress, ByVal subn As Net.IPAddress) As Net.IPAddress
Dim host32 As UInteger = GetBinaryAddress(addr.ToString)
Dim subn32 As UInteger = GetBinaryAddress(subn.ToString)
Dim broad32 As UInteger = host32 Or Not (subn32)
Dim _mybytes As Byte() = {0, 0, 0, 0}
_mybytes(0) = (broad32 And &HFF000000) >> 24
_mybytes(1) = (broad32 And &HFF0000) >> 16
_mybytes(2) = (broad32 And &HFF00) >> 8
_mybytes(3) = broad32 And &HFF
Dim broadcast As Net.IPAddress = Net.IPAddress.None
Net.IPAddress.TryParse(_mybytes(0).ToString + "." + _mybytes(1).ToString + "." + _mybytes(2).ToString + "." + _mybytes(3).ToString, broadcast)
Return broadcast
End Function
Private Function GetBinaryAddress(ByVal addr As String) As UInteger
Dim _hostaddr_bytes As String() = addr.ToString.Split(".")
Dim _host_int32 As UInteger = (Convert.ToUInt32(_hostaddr_bytes(0)) << 24) + (Convert.ToUInt32(_hostaddr_bytes(1)) << 16) + (Convert.ToUInt32(_hostaddr_bytes(2)) << 8) + Convert.ToUInt32(_hostaddr_bytes(3))
Return _host_int32
End Function
Private Function GetBinaryAddress(ByVal add As Net.IPAddress) As UInteger
Dim addr As String = add.ToString
Dim _hostaddr_bytes As String() = addr.ToString.Split(".")
Dim _host_int32 As UInteger = (Convert.ToUInt32(_hostaddr_bytes(0)) << 24) + (Convert.ToUInt32(_hostaddr_bytes(1)) << 16) + (Convert.ToUInt32(_hostaddr_bytes(2)) << 8) + Convert.ToUInt32(_hostaddr_bytes(3))
Return _host_int32
End Function
Private Function MessaggeIsForUS(ByVal mess As String) As Boolean
Dim localaddr() As String = mess.Split(",")
localaddr(1) = localaddr(1).Remove(0, 4)
Dim dest32 As UInteger = GetBinaryAddress(localaddr(1))
If ((dest32 And _local32) = _local32) Then
Return True
Else
Return False
End If
End Function
End Class
The sub i refer to is "StartListening".
Some comments on the code:
the New sub essentially finds the local main ip address and related subnet mask, from those it calculates the sub-network broadcast ip.
StartListening and StopListening should be self explanatory.
ProcessReceive is the internal sub that encapsulates system.net.udpclient doing the hardwork.
SendMessage is the exposed interface to receive the string to send from the parent class.
The rest are service subs and functions.