I am writing some software for some barcode scanners running Windows CE 5.
The software needs to communicate with a server and obtain data. It connects to some software running on a separate computer using a TcpClient.
When it sends data across to the server software, the server software sends a message back saying "Received ## Bytes - " and the command that was sent, so I can clarify that the command has been received correctly (this is because I was having a problem where the string was being "mixed up")
When the barcode scanner receives a response, I want it to then wait for another response with the results of the command.
The problem I'm having, is that the when the TcpClient receives data it calls a Sub named ReceivingMessage, but it only appears to do this after the sub that sends the message finishes.
The SendMessage function is as follows
Public Function SendMessage(ByVal SendString As String) As Boolean
Dim _Result As Boolean = False
Dim _SendString As String = ""
Try
_Response = ""
If Not _Connection Is Nothing AndAlso _Connection.Client.Client.Connected AndAlso Not _Connection.Stream Is Nothing Then
Dim _Now As String = Format(CInt(Now.Day), "00") & "/" & Format(CInt(Now.Month), "00") & "/" & Format(CInt(Now.Year), "0000") & " " & Format(CInt(Now.Hour), "00") & ":" & Format(CInt(Now.Minute), "00") & ":" & Format(CInt(Now.Second), "00")
_SendString = _Now & CmdSpcr & SendString & EndOfMessageString
Dim buffer() As Byte = System.Text.Encoding.ASCII.GetBytes(_SendString)
_Connection.Stream.Write(buffer, 0, buffer.Length)
_Result = True
End If
_WaitingForResponse = True
'Wait for a response here
If _Response.StartsWith("Received ") And _Response.EndsWith(" Bytes - " & _SendString) Then
_Result = True
Else
_Result = False
End If
Catch ex As Exception
RaiseEvent DisplayMessage(ex.ToString, MsgBoxStyle.Critical, "Error")
_Result = False
End Try
Return _Result
End Function
The ReceivingMessage sub is very simple and is called as part of another class
Private Sub ReceivingMessage(ByVal message As String)
If _WaitingForResponse Then
_Response = message
Else
RaiseEvent MessageReceived(message)
End If
End Sub
Here is the class
Imports System.Net.Sockets
Imports System.Net
Public Class modConnectionInfo
Private _ReceivingMessageMethod As Action(Of String)
Private _Buffer(9999) As Byte
Private _Client As TcpClient
Private _LastReadLength As Integer
Private _Stream As NetworkStream
Public ReadOnly Property ReceivingMessageMethod() As Action(Of String)
Get
Return _ReceivingMessageMethod
End Get
End Property
Public ReadOnly Property Client() As TcpClient
Get
Return _Client
End Get
End Property
Public ReadOnly Property Stream() As NetworkStream
Get
Return _Stream
End Get
End Property
Public ReadOnly Property LastReadLength() As Integer
Get
Return _LastReadLength
End Get
End Property
Public Sub AwaitData()
_Stream.BeginRead(_Buffer, 0, _Buffer.Length, AddressOf DoReadData, Me)
End Sub
Public Sub Close()
If _Client IsNot Nothing Then _Client.Close()
_Client = Nothing
_Stream = Nothing
End Sub
Private Sub DoReadData(ByVal result As IAsyncResult)
Dim info As modConnectionInfo = CType(result.AsyncState, modConnectionInfo)
Try
If info._Stream IsNot Nothing AndAlso info._Stream.CanRead Then
info._LastReadLength = info._Stream.EndRead(result)
If info._LastReadLength > 0 Then
Dim message As String = System.Text.Encoding.ASCII.GetString(info._Buffer, 0, info._Buffer.Count)
message = message.Replace(vbNullChar, "")
info._ReceivingMessageMethod(message)
End If
ReDim info._Buffer(9999)
info.AwaitData()
End If
Catch ex As Exception
info._LastReadLength = -1
info._ReceivingMessageMethod(ex.Message)
End Try
End Sub
Public Sub New(ByVal address As IPAddress, ByVal port As Integer, ByVal ReceivingMessage As Action(Of String))
_ReceivingMessageMethod = ReceivingMessage
_Client = New TcpClient
_Client.Connect(address, port)
_Stream = _Client.GetStream
End Sub
End Class
Does anyone know how I can get the SendMessage sub to pause at the part where I've put "'Wait for a response here" and allow the ReceivingMessage sub to run before continuing?
The way this class is called is as follows
_Connection = New modConnectionInfo(IPAddress.Parse(ServerIP), CInt(ServerPort), AddressOf ReceivingMessage)
If _Connection.Client.Client.Connected Then
_Connected = True
End If
_Connection.AwaitData()
Any help would be greatly appreciated