0

My goal is to have this be async, so it can be added to an existing pulse code base.

I'm writing this to get a working example that I can then merge into it. Using a windows console app for now.

I have it connecting using WSAConnect, but I can't figure out how to add events. My googling has left me with WSACreateEvent, and likely something with Overlapping I/O, but I either end up on Microsoft's website, where it explains them, but doesn't provide examples, or I find examples that appear to be above my understanding.

Worth mentioning, I also believe I need to be using WSAConnectEx to make that async, however until I can figure out how to add events, that doesn't help me just yet.

Note 2: At the moment, it requires the IP address, not a hostname. Something that needs changed, however, without events the little details are less important.

This has been hacked together by googling...

#pragma comment(lib,"Ws2_32.lib")

#include <iostream>
#include <WinSock2.h>
#include <ws2tcpip.h>
#include <stdio.h>
#include <stdlib.h>   // Needed for _wtoi

int main()
{
    // Declare and initialize variables
    WSADATA wsaData = { 0 };
    int iResult = 0;

    SOCKET sock = INVALID_SOCKET;
    int iFamily = AF_INET;
    int iType = SOCK_STREAM;
    int iProtocol = IPPROTO_TCP;
    DWORD dwFlags = WSA_FLAG_OVERLAPPED;

    // Initialize Winsock
    iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
    if (iResult != 0) {
        wprintf(L"WSAStartup failed: %d\n", iResult);
        return 1;
    }
    
    sock = WSASocket(iFamily, iType, iProtocol, NULL, 0, dwFlags);
    if (sock == INVALID_SOCKET)
        wprintf(L"WSASocket function failed with error = %d\n", WSAGetLastError());
    else 
    {
        wprintf(L"WSASocket function succeeded\n");

        // Find a way to make it non-blocking here.. I believe

        // set up sockaddr
        struct sockaddr_in saServer;

        saServer.sin_family = AF_INET;
        inet_pton(PF_INET, "###.###.###.###", &(saServer.sin_addr));

        int portno = 6667;
        saServer.sin_port = htons(portno);

        iResult = WSAConnect(sock, (SOCKADDR*)&saServer, sizeof(saServer),NULL,NULL,NULL,NULL);
        wprintf(L"WSAConnect return = %d\n", iResult);
        if (iResult != 0)
        {
            wprintf(L"WSAConnect function failed with error = %d\n", WSAGetLastError());
            return 1;
        }

        // EDIT - Below while statement has to be non-blocking. It will be executed every frame.


        while (TRUE)
        {
             // my unrelated code here
        }





        iResult = closesocket(sock);
        if (iResult == SOCKET_ERROR) 
        {
            wprintf(L"closesocket function zfailed with error = %d\n", WSAGetLastError());
            WSACleanup();
            return 1;
        }
    }
    WSACleanup();

    return 0;
}

// When data is received in full, this is triggered
void SomeEventFunction(args)
{
     // parse the received data here
}

Output:

WSASocket function succeeded
WSAConnect return = 0
Kannkor
  • 11
  • 3
  • 1
    What does "add events" mean to you, exactly? Please clarify the problem. And FYI, there is no `WSAConnectEx()`, you are thinking of `ConnectEx()` instead. – Remy Lebeau Mar 11 '22 at 00:23
  • I doubt that WASCreateEvent does what you want. – pm100 Mar 11 '22 at 00:25
  • 1
    https://stackoverflow.com/questions/5037832/handling-asynchronous-sockets-in-winsock – pm100 Mar 11 '22 at 00:26
  • @RemyLebeau Guess that may be the problem! What I would like, is an "event", or a triggered function whenever an event has happened. Such as there is a message that has been received. Maybe more straight forward example, is if I use WSAConnectEx to make it async, is there not an event/callback to say the connection has completed with a connection code (error or success)? – Kannkor Mar 11 '22 at 00:27
  • In that case, read the link pm100 provided. There are MANY different ways to approach this. – Remy Lebeau Mar 11 '22 at 00:29
  • @RemyLebeau I read the link, do you have a specific way you think I should approach this? My understanding of the two ways I'm seeing, are constantly scanning WSAAsyncSelect to get a list of messages/events, then read them. The second way, is to set up Overlapped I/O with events. I'd prefer to work on only 1 solution for now, any direction would be appreciated. – Kannkor Mar 11 '22 at 00:51
  • @Kannkor There are 4 asynchronous approaches described in that link: 1) non-blocking I/O; 2) `WSAAsyncSelect()`, which sends window messages to a designated `HWND` when events happen; 3) `WSAEventSelect()`, which signals an event object when events happen (you might have been thinking of this in a polling loop, though that is not strictly required); 4) Overlapped I/O. In any case, which approach you decide to use really depends on the rest of the code you are integrating the socket I/O with. The code you have presented so far would not benefit from any kind of asynchronous handling at all. – Remy Lebeau Mar 11 '22 at 02:21
  • @RemyLebeau I edited to add in sudo code to try to explain what I'm trying to accomplish in the end. This connection will stay active and listening/sending messages indefinitely. When the connection sends a message, I want to read/parse it, and perform some action, be send a message back to the server, and/or something unrelated to the above. – Kannkor Mar 11 '22 at 02:38
  • @Kannkor then you are probably better off just not using asynchronous I/O at all. Normal blocking I/O in a dedicated worker thread would be simpler. Especially since you are acting as a client, not as a server. – Remy Lebeau Mar 11 '22 at 04:14

0 Answers0