Public Class PDAviaTCP
Private curListen As System.Net.Sockets.TcpListener
Private quitFlag As Boolean
Private myTimer As System.Windows.Forms.Timer
Private lSock As System.Net.Sockets.TcpClient
Private netStream As System.Net.Sockets.NetworkStream
Private linOpt As System.Net.Sockets.LingerOption
Private bTimedOut As Boolean
#Region "Constructors and Destructors"
Public Sub New()
curListen = New System.Net.Sockets.TcpListener(System.Net.IPAddress.Any, 2000)
quitFlag = True
'Create the timer
myTimer = New System.Windows.Forms.Timer
'Need to tell it where to send time tick messages.
AddHandler myTimer.Tick, AddressOf TimerEventProcessor
'This is set so that we can know the status if nothing is received.
bTimedOut = False
' Sets the timer interval to 5 seconds.
myTimer.Interval = 5000
myTimer.Enabled = False
linOpt = New System.Net.Sockets.LingerOption(True, 5)
End Sub
Public Sub dispose()
myTimer.Dispose()
curListen.Stop()
If Not lSock Is Nothing Then
lSock.Close()
End If
End Sub
#End Region
#Region "Public Functions"
'StartListening puts the TCPListener class into listening mode. This must be called
'for a connection to be received.
Public Sub StartListening()
Try
curListen.Start()
Catch ex As Exception
'Regardless of the exception, this may be ok.
MsgBox("Exception was thrown during start." & vbNewLine & vbNewLine & ex.Message, MsgBoxStyle.Information, "Possible Issue")
End Try
End Sub
'This function simply checks for a connection, but does not do anything except return
'true if a connection is pending.
Public Function CheckForConnection() As Boolean
Try
CheckForConnection = curListen.Pending
Catch
CheckForConnection = False
End Try
End Function
'This function simply accepts the connection and stops the listener.
Public Function GetConnection() As Boolean
Try
If curListen.Pending Then
lSock = curListen.AcceptTcpClient
lSock.LingerState = linOpt
netStream = lSock.GetStream
curListen.Stop()
GetConnection = True
Else
GetConnection = False
End If
Catch ex As Exception
GetConnection = False
End Try
End Function
'Stops listening without bothering with whether or not a connection is available.
Public Sub StopListening()
curListen.Stop()
End Sub
'Use this to send data to the socket. No check is made to see that
'the socket is available. The return is false if any exceptions are raised.
Public Function SendData(ByVal st1 As String) As Boolean
Dim sendBuff(2048) As Byte
'Try
sendBuff = System.Text.Encoding.Default.GetBytes(st1.ToCharArray())
netStream.Write(sendBuff, 0, sendBuff.GetLength(0))
SendData = True
'Catch ex As Exception
SendData = False
'End Try
End Function
'Use this to get data from the socket. This will time out in 5s.
Public Function RetrieveData() As String
Dim recBuff(2048) As Byte
Dim recCount As Integer
Dim st1 As String
Dim hasRead As Boolean
hasRead = False
'Get ready to read.
quitFlag = True
myTimer.Enabled = True
Try
Do While quitFlag
If netStream.DataAvailable Then
recCount = netStream.Read(recBuff, 0, recBuff.GetLength(0))
End If
If recCount > 0 Then
hasRead = True
myTimer.Enabled = False
'Turn it into a string.
st1 &= System.Text.Encoding.ASCII.GetString(recBuff, 0, recCount)
st1 = st1
'Clear out the buffer.
recBuff.Clear(recBuff, 0, recBuff.GetLength(0))
recCount = 0
Else
'If hasRead is set, then something has been received, but the last loop
'returned nothing. Therefore, we are done reading.
If hasRead Then
'This is simply cleared to stop the loop.
quitFlag = False
End If
'DoEvents, but only if nothing is coming in!
Application.DoEvents()
End If
Loop
Catch ex As Exception
'Nothing can be done here, but that's ok.
MsgBox(ex.Message)
End Try
'Get out.
Me.bTimedOut = False
RetrieveData = st1
End Function
'If this is true, then the time event fired. Basically, this means that if
'RetrieveData() returned an empty string, it was because of timing out.
Public Function TimedOut() As Boolean
TimedOut = Me.TimedOut
End Function
#End Region
#Region "Private Functions"
'The timer is used to stop the endless loop in RetrieveData(), and for no other
'purpose. If the event fires, the bTimedOut variable is set.
Private Sub TimerEventProcessor(ByVal myObject As Object, ByVal myEventArgs As EventArgs)
myTimer.Enabled = False
quitFlag = False
Me.bTimedOut = True
End Sub
#End Region
End Class
Public Class ThreadedConnection
Private theThread As System.Threading.Thread
Private mDBHolder As dbHolder
Private mPDAvia As PDAviaTCP
Private Shared mWriteDone As System.Threading.ManualResetEvent
Public Sub New()
theThread = New System.Threading.Thread(AddressOf DoConnection)
'This may be somewhat sketchy, but it should work just fine.
mDBHolder = dbC.Copy
theThread.IsBackground = True
mPDAvia = New PDAviaTCP
mWriteDone = New System.Threading.ManualResetEvent(False)
End Sub
Public Sub Dispose()
StopConnection()
mWriteDone.Close()
mPDAvia.dispose()
mDBHolder.Dispose()
End Sub
'This checks the database in the connection thread, and if it is valid, the thread
'is started.
Public Function StartConnection() As Boolean
If mDBHolder.IsValid Then
theThread.Start()
End If
StartConnection = mDBHolder.IsValid
End Function
Public Sub StopConnection()
'The event will be signaled (go ahead) throughout, with the exception of writing
'to the db. For that alone it will be unsignaled (wait). Once the write is complete
'the event will be signaled.
mWriteDone.WaitOne()
'At which point, it would be a good idea to stop the comport from listening.
mPDAvia.StopListening()
'And end the thread.
theThread.Abort()
End Sub
Private Sub DoConnection()
Dim st1 As String
Dim st2 As String
Dim v As Integer
Dim outData As String
'First make the string data for outputting.
outData = mDBHolder.CreateData()
mPDAvia.StartListening()
mWriteDone.Set()
Do
Do
Application.DoEvents()
Loop While Not mPDAvia.CheckForConnection
'If you get here, then a connection is ready.
If mPDAvia.GetConnection() Then
'Send the type info across.
mPDAvia.SendData("1")
st1 = mPDAvia.RetrieveData
'Next, send out the output data.
mPDAvia.SendData(outData)
'Now, st1 holds either 1 (no data) or 4 (new data coming) or 5 (all data coming)
v = Val(st1)
If v > 1 Then
'Now the data coming back should be received.
st2 = mPDAvia.RetrieveData
mWriteDone.Reset()
mDBHolder.UpdateTablesWithXML(st2)
mWriteDone.Set()
End If
End If
'Now it is necessary to start listening again.
mPDAvia.StartListening()
Loop While True
End Sub
End Class