We help IT Professionals succeed at work.

Acknowledging back from UDP port


I am developing a GPS tracking application. The GPS data is coming into a UDP port 2000 from 150 GPS devices . The server need to acknowledge back to device everytime the data comes  .

 The application works perfect for a single  GPS device  in a single thread. But when I test (with a simulator application sending data from 150 different ports from  another machine)  I get following error  

A blocking operation was interrupted by a call to WSACancelBlockingCall

 What I did is , keep listening to the UDP port  in a thread and when data arrives, close the UDPClient temporarily and send acknowledgement from the socket and open the UDPClient and listen again   .
 As I told, it works  fine in a single thread . But the problem is , I can't acknowledge in the same thread of receiving because many devices are reporting at the same time . ( About  20% data coming in is lost  when single thread is used)

 Please help me with the  pseudocode (and sample code, if possible ) I have to use
   
Dim receivingUdpClient As UdpClient
    Dim receiveBytes As [Byte]()
    Public ThreadReceive As System.Threading.Thread
    Public RemoteIpEndPoint As New System.Net.IPEndPoint(System.Net.IPAddress.Any, 0)
   
 '''' Routine to listen UDP data 
    Public Sub ReceiveMessages()

        Try
            receiveBytes = receivingUdpClient.Receive(RemoteIpEndPoint)   ''' recieve from UDP port

             
            NewInitializeThread()  '' Initialise a new thread
            GC.Collect()

        Catch ex As Exception

        End Try

    End Sub


    Public Sub NewInitializeThread()
       ''' Actually this runs in a different thread
            AcknowledgeBack()  '' Routine to acknowledgeback 


        ThreadReceive = New System.Threading.Thread(AddressOf ReceiveMessages)
        ThreadReceive.Start()

    End Sub

 Sub AcknowledgeBack(ByVal strIP As String, ByVal intPort As String, ByVal strHex As String)
        Dim strAcknowledgeHex As String

        receivingUdpClient.Close()

         
        SendWithUDPSocket(strIP, intPort, strAcknowledgeBytes)

        If Not receivingUdpClient Is Nothing Then
            receivingUdpClient = Nothing
        End If

        receivingUdpClient = New System.Net.Sockets.UdpClient(SocketNO)

    End Sub

   
   Function SendWithUDPSocket(ByVal LocalIP As IPAddress, ByVal LocalPort As Long _
                                 , ByVal MsgBytes As Byte())

        Dim _socket As Socket
        Try

            _socket = New Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp)
            Dim endPoint = New IPEndPoint(LocalIP, LocalPort)
            _socket.Bind(endPoint)



            Dim _remoteEndPoint As IPEndPoint

            _remoteEndPoint = RemoteIpEndPoint ''New IPEndPoint(GLOIP, GLOINTPORT)
            _socket.SendTo(MsgBytes, MsgBytes.Length, SocketFlags.None, _remoteEndPoint)

            _socket.Close()



        Catch ex As Exception
            MsgBox("Error - " & ex.Message)
        End Try
        _socket = Nothing

        'Return _socket
        GC.Collect()

    End Function

Open in new window

Comment
Watch Question

This is not the best approach when dealing with even a single connection. If you can explain why you close the socket and then create a new one and send response and then recreate the original socket it may help understand the requirements.
In general, it would be more beneficial if you can look into the asynchronous programming style. MSDN has quite some samples on that.
The best way to address large number of connections and heavy throughput is to have a queued design. think of it as a reader/writer case, where you read packets and put into queue and a processor processes and queues the responses that are then dispatched. I'm not sure whether that applies but you can consider it.
 

Author

Commented:
I have closes and open UDPclient  because otherwise it was giving an error when I send acknowledgemnt while I use the same port for receiving .

 I am doing socket programming for the first time. ( I have been coding vb.net for quite sometime, though)  can you please provide some sample code for asynchronous programming ?
>> I have closes and open UDPclient  because otherwise it was giving an error when I send acknowledgemnt while I use the same port for receiving
That's odd.
 
Here are some tutorials to start with
 http://www.codeproject.com/KB/IP/ChatAppAsynchUDPSocks.aspx
http://msdn.microsoft.com/en-us/magazine/cc163648.aspx
http://msdn.microsoft.com/en-us/magazine/cc300760.aspx 
You should use two udp, one for litening, and one for sending. i have implemented this in a network application using computer,

when there is data arrival in the litening udp, the udp remot port and ip get set to the device ip and port, pass this to the second udp to send your message

do not use just two since you say you hav150 devices, you should spawn new udp for each device, this way, there will be no blocking

Author

Commented:
Helped in solving .