Not so much a question as I managed to figure it out, but not being a Win32 API guru it took took a while, and I thought I'd post here to save someone else the time.
You can use the WSAAsyncSelect winsock function with CVI, by using GetCVIWindowHandle, and RegisterWinMsgCallback to connect the Windows event to a CVI callback. Example code below:
#define MY_SERVER_PORT 13579
static SOCKET sock = INVALID_SOCKET;
static int panel = -1;
//----------------------------------------------------------------------------
int main (int argc, char *argv[])
{
struct sockaddr_in address;
WSADATA wsa_data;
HWND hwnd;
int wmsg;
int res;
// initialize GUI
res = InitCVIRTE (0, argv, 0);
if (res == 0) return -1; /* out of memory */
panel = LoadPanel (0, "datagramUI.uir", PANEL);
if (panel < 0) return -1;
DisplayPanel (panel);
// initialize the winsock library
WSAStartup (MAKEWORD (2,2), &wsa_data);
// create a UDP socket
sock = socket (AF_INET, SOCK_DGRAM, 0);
if (sock == INVALID_SOCKET) HandleError ();
// bind the socket to the given port
address.sin_family = AF_INET;
address.sin_port = htons (MY_SERVER_PORT);
address.sin_addr.s_addr = INADDR_ANY;
res = bind (sock, (struct sockaddr*)&address, sizeof(address));
if (res == SOCKET_ERROR) HandleError ();
// create a windows event id and attach it to a cvi callback
hwnd = (HWND) GetCVIWindowHandle ();
wmsg = RegisterWinMsgCallback (WSACallback, NULL, NULL, 0, &res, TRUE);
if (wmsg == 0) HandleError();
// tell winsock to generate that event when data is available to read
res = WSAAsyncSelect (sock, hwnd, wmsg, FD_READ);
if (res == SOCKET_ERROR) HandleError ();
// run program
RunUserInterface ();
// clean up
DiscardPanel (panel);
closesocket (sock);
WSACleanup();
return 0;
}
void CVICALLBACK WSACallback (WinMsgWParam wParam, WinMsgLParam lParam,
void *callbackData)
{
struct sockaddr_in address;
int addr_len = sizeof (address);
char message[640];
char data[512];
int res;
if (wParam != sock) {
MessagePopup ("Winsock callback Error", "Event is for a different socket");
return;
}
if (lParam != FD_READ)
MessagePopup ("Winsock callback Error", "This is not a read event");
return;
}
// read data
res = recvfrom (sock, data, sizeof(data), 0,
(struct sockaddr*)&address, &addr_len);
if (res == SOCKET_ERROR) HandleError ();
else {
sprintf (message, "%s:%d - '%.*s'\n", inet_ntoa(address.sin_addr),
ntohs (address.sin_port), res, data);
MessagePopup ("Message Received", message);
}
}