I'm trying to write a UDP application that sends a message and waits for a response before sending another.
To do this I am using a Semaphore initialising with the total threads, up to 6, and a count of 1.
In the Semaphore thread, I have a loop that runs as long as the semaphore is not complete ie. doesn't have a response.
The issue is with UDP, I'm fairly new to this class, and have been struggling a lot.
So far I am successful with sending the data, but have experienced exceptions when trying to receive.
In the UDP Manager Class, I have created an Rx thread which listens, and adds the data to a buffer. The buffer gets called each time a Semaphore thread is waiting for a response.
Semaphore thread:
Rx Thread:
To do this I am using a Semaphore initialising with the total threads, up to 6, and a count of 1.
In the Semaphore thread, I have a loop that runs as long as the semaphore is not complete ie. doesn't have a response.
The issue is with UDP, I'm fairly new to this class, and have been struggling a lot.
So far I am successful with sending the data, but have experienced exceptions when trying to receive.
In the UDP Manager Class, I have created an Rx thread which listens, and adds the data to a buffer. The buffer gets called each time a Semaphore thread is waiting for a response.
Semaphore thread:
VB.NET:
Private Sub Init_Semaphore(ByVal TotalThreads As Integer)
ListBox1.Items.Add("== Start ======")
Dim SemaphoreCount As Integer = 1
Dim Threads(TotalThreads) As Thread
Dim Sema As Semaphore = New Semaphore(SemaphoreCount, SemaphoreCount)
TotalCompleted = 0
For i As Integer = 0 To TotalThreads - 1
UDPManager.AddCommandToBuffer(IPAddress, TxPort, RxPort, MessageList.Item(i), "J" & MessageList.Item(i).Substring(0, 1))
Threads(i) = New Thread(New ParameterizedThreadStart(AddressOf AccessCode_WithSemaphore))
Threads(i).IsBackground = True
Threads(i).Name = MessageList.Item(i)
Threads(i).Start(Sema)
Next
End Sub
Private Sub AccessCode_WithSemaphore(ByVal ObjSemaphore As Object)
Dim IsComplete As Boolean = False
Dim l_Semaphore As Semaphore = DirectCast(ObjSemaphore, Semaphore)
Do While IsComplete = False
Dim Message As String = Thread.CurrentThread.Name
Dim Response As UDP_Manager.Cls_UDPManager.Struct_Response = Nothing
If l_Semaphore.WaitOne(200, False) Then
Try
ListBox1.BeginInvoke(New ParameterizedThreadStart(AddressOf UpdateUILB1), New Object() {"Thread ID: J" & Message.Substring(0, 1) & " Sending message: " & Message})
Do Until Response.Response <> Nothing
UDPManager.ReceiveMessage("J" & Message.Substring(0, 1))
Response = UDPManager.GetMessageFromRxBuffer("J" & Message.Substring(0, 1))
Loop
Thread.Sleep(50)
Catch ex As Exception
Finally
l_Semaphore.Release()
ListBox1.BeginInvoke(New ParameterizedThreadStart(AddressOf UpdateUILB1), New Object() {"Thread ID: J" & Message.Substring(0, 1) & " Message received: " & Response.Response})
IsComplete = True
'SemaphoreReady = True
TotalCompleted += 1
If TotalCompleted = MessageList.Count Then
SemaphoreReady = True
End If
End Try
Else
'Waiting to enter
End If
Loop
End Sub
Rx Thread:
VB.NET:
Private Sub ReceiveCallback(ByVal ar As IAsyncResult)
Dim u As UdpClient = CType((CType(ar.AsyncState, Cls_UDPState)).UDPClient, UdpClient)
Dim e As IPEndPoint = CType((CType(ar.AsyncState, Cls_UDPState)).EndPoint, IPEndPoint)
Try
Dim ReceiveBytes() As Byte = u.EndReceive(ar, e)
Dim ReceiveString As String = Encoding.ASCII.GetString(ReceiveBytes)
If Not ReceiveString = Nothing Then
RxBufferInUse = True
Dim Response As New Struct_Response
With Response
.Response = ReceiveString.Substring(0, ReceiveString.Length - 2)
.Sender = CommandBuffer.Item(0).Sender
.RxTime = Now
End With
ResponseBuffer.Add(Response)
Threading.Thread.Sleep(300)
If CommandBufferInUse = False Then
CommandBufferInUse = True
CommandBuffer.RemoveAt(0)
CommandBufferInUse = False
End If
Else
Dim i As Integer = 0
End If
Catch ex As Exception
End Try
RxBufferInUse = False
SendNextMessage = True
End Sub
Public Sub ReceiveMessage(ByVal Sender As String)
If CommandBuffer.Count > 0 Then
Dim EndPoint As IPEndPoint
EndPoint = New IPEndPoint(IPAddress.Any, 0)
If RxUDP Is Nothing Then
Try
RxUDP = New UdpClient(CommandBuffer.Item(0).IPConfig.RxPort)
State = New Cls_UDPState
State.EndPoint = EndPoint
State.UDPClient = RxUDP
RxThread = New AsyncCallback(AddressOf ReceiveCallback)
Catch ex As Exception
End Try
End If
Try
RxUDP.BeginReceive(RxThread, State)
Catch ex As Exception
[COLOR=#ff0000]'Mostly fails here with this exception:
'System.Net.Sockets.SocketException = {"An operation on a socket could not be performed because the system lacked sufficient buffer space or because a queue was full"}[/COLOR]
End Try
End If
End Sub
Public Function GetMessageFromRxBuffer(ByVal Sender As String) As Struct_Response
RxBufferInUse = True
If ResponseBuffer.Count > 0 Then
For i As Integer = ResponseBuffer.Count - 1 To 0 Step -1
If ResponseBuffer.Count > 0 Then
Try
If ResponseBuffer.Item(i).Sender = Sender Then
Dim Response As Struct_Response = ResponseBuffer.Item(i)
If ResponseBuffer.Count > 0 Then
Try
ResponseBuffer.RemoveAt(i)
Catch ex As Exception
Dim j As Integer = 0
End Try
RxBufferInUse = False
Return Response
Else
Exit For
End If 'response count
End If 'sender
Catch ex As Exception
Dim j As Integer = 0
End Try
Else
Exit For
End If 'response count
Next
Else
End If 'response count
RxBufferInUse = False
Return Nothing
End Function