LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

UDP Receive Callback Functions?

Is there a way to have a callback function for UDP traffic, just like how there is TCPcallback() for TCP?  I have an application sending out data requests frequently, but the blocking waits with recvfrom() as in the UDP example application are hurting the responsiveness of the application.  I would like to move the communiation functions off to their own thread so they don't tie up everything else, but the thread won't help much if it has blocking waits in them.
0 Kudos
Message 1 of 5
(5,904 Views)
UDP support is not built-in to CVI. The UDP example actually just makes calls into the Windows SDK to create UDP connections. Because of this, there are no callbacks associated with UDP.

Brandon Vasquez | Software Engineer | Integration Services | National Instruments
0 Kudos
Message 2 of 5
(5,872 Views)
Why not use a short timeout, create a separate thread to do the read, and have it sleep after a timeout, allowing the UDP packet to arrive and be read on a subsequent read attempt?

That way you're not busy-waiting on the read more than you need to be.

Menchar
0 Kudos
Message 3 of 5
(5,846 Views)

ioctrlsocket() called for FIONREAD will return the number of bytes available.  This can be used in a loop to check if data is available without blocking the thread.  And alternative is to use something like an async timer or a separate thread to monitor the availability of udp data.  The thread would pull data from the udp socket and place it into a ThreadSafeQueue.  The TSQ can be polled by the main thread to determine when data is available or a callback can be generated directly by the TSQ. 

A warning about FIONREAD, do not expect all of your data to arrive at one time.  UPD can split data across packets which leads to issues if poll for a specific byte count with FIONREAD.  This even has an entry on the "Winsock Lame List."

0 Kudos
Message 4 of 5
(5,826 Views)
NI should implement UDP in the CVI pacage for connectionless data transmission, but for the time beeing the you can use the following code to install UDP callbacks for reading UDP datagrams:
 
jd
 
 
int CVIFUNC_C InstallUdpCallback(UDPHANDLE connectionHandle, UDPCallBack Callback_Function,  void *Callback_Data)
{
 int callBackHandle;
 HWND hWnd;
 
 // Check that we have a callback routine and that the socket handle is initialized.
 if (Callback_Function == 0 || connectionHandle == 0)  return -WSAENOTSOCK;
 
 // Make an invisible  panel beacause we need a panel handle
 if ((callBackHandle = NewPanel (0, "", 1, 1, 10, 10)) <0)  return -2;
 
 // Install a window message into cvi message system
 if (InstallWinMsgCallback (callBackHandle, WM_SOCKET, Callback_Function, VAL_MODE_INTERCEPT, Callback_Data, (int*) &hWnd)<0) return -2;
 
 // Install async callback routine for socket messages
 if(WSAAsyncSelect(connectionHandle, hWnd, WM_SOCKET, FD_READ) != 0 )  return (-gpWSAGetLastError());
 
    return callBackHandle;
}
0 Kudos
Message 5 of 5
(5,813 Views)