LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

WSAAsyncSelect

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);
    }
}

Message 1 of 1
(3,857 Views)