0
votes

Here is Main.cpp up to the point where the error happens:

int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmdLine, int nShowCmd)
{
    if(SUCCEEDED(CoInitialize(NULL)))
    {
        {
            Game game;

            game.CreateRessources(hInst);

            game.ShowMainScreen();

            game.pWinsock->Initialize(game.Getm_hWnd());

game.Getm_hWnd return the private HWND m_hWnd.

Here is Game::CreateRessources(HINSTANCE):

void Game::CreateRessources(HINSTANCE hInst)
{   
    m_hWnd=CreateWindowClass(hInst);

    pMessageLog=CreateMessageLog();
    pD2DResources=CreateD2DResources(m_hWnd);
    pWinsock=CreateWinsock();

}

There is CreateWinsock():

Winsock* CreateWinsock()
{
    Winsock* pWinsock=new Winsock;

    return pWinsock;
}

Winsock::Winsock:

Winsock::Winsock() : Socket(NULL) { }

And finally, Winsock::Initialize(HWND):

void Winsock::Initialize(HWND hwnd)
{
    WSADATA wsaDat;

    SendMessage(hwnd, LOG_ADD, NULL, (LPARAM)L"Initializing winsock... ");

    int nResult = WSAStartup(MAKEWORD(2,2),&wsaDat);
    if(nResult!=0)
    {
        MessageBox(NULL,"Winsock initialization failed","Critical error",MB_ICONERROR);
        SendMessage(hwnd,WM_DESTROY,NULL,NULL);
    }

    SendMessage(hwnd, LOG_ADD, NULL, (LPARAM)L"Done!\nCreating a socket... ");

    Socket=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
    if(Socket==INVALID_SOCKET)
    {
        MessageBox(NULL,"Socket Creation failed","Critical error",MB_ICONERROR);
        SendMessage(hwnd,WM_DESTROY,NULL,NULL);
    }

    SendMessage(hwnd, LOG_ADD, NULL, (LPARAM)L"Done!\nRequesting Windows message-based notification of network events... ");

    nResult=WSAAsyncSelect(Socket,hwnd,WM_SOCKET,(FD_CLOSE|FD_READ));
    if(nResult)
    {
        if(WSAGetLastError()==WSAENOTSOCK)
            MessageBox(hwnd,"WSAENOTSOCK Error!","Error",NULL);
        MessageBox(NULL,"WSAAsyncSelect failed","Critical error",MB_ICONERROR);
        SendMessage(hwnd,WM_DESTROY,NULL,NULL);
    }

    /* More code */
}

The line if(WSAGetLastError()==WSAENOTSOCK) returns true. WSAENOTSOCK means the following:

"Socket operation on nonsocket. An operation was attempted on something that is not a socket. Either the socket handle parameter did not reference a valid socket, or for select, a member of an fd_set was not valid."

Edit: There is my Winsock class:

class Winsock{
public:
    Winsock();

    void Initialize(HWND);

    void ReceiveMsg();

private:
    SOCKET Socket;
    static const char* server;
    static const int port;
};

As far as I can tell, Socket IS a socket, and a valid one. How comes I receive that error anyway?

1
Is SendMessage one of your functions? Can't find it in the winsock API, there's only send. - us2012
It is a WinAPI function. It sends a message to the WinProc. - Mickael Bergeron Néron
Are you sure you are not closing socket somewhere in WndProc by the time you reach WSAAsyncSelect? - Roman R.
100% sure. Actually, I still didn't write any code to close my socket. - Mickael Bergeron Néron

1 Answers

2
votes

You are initializing the Socket member to the wrong value in the Winsock constructor - NULL instead of INVALID_SOCKET. They are not the same value.

You are calling WSAAsyncSelect() regardless of whether socket() succeeds or fails. You are displaying error messages if things fail, but you are not stopping your code when they do fail. You need to clean up your error handling.

On a side note, you need to use DestroyWindow() instead of sending WM_DESTROY messages manually.

Try this instead:

class Winsock
{
public:
    Winsock();

    void Initialize(HWND);

    void ReceiveMsg();

private:
    SOCKET m_Socket;
    ...
};

Winsock::Winsock()
    : m_Socket(INVALID_SOCKET)
{
}

void Winsock::Initialize(HWND hwnd)
{
    SendMessage(hwnd, LOG_ADD, 0, (LPARAM)L"Initializing winsock... ");

    WSADATA wsaDat = {0};
    if (WSAStartup(MAKEWORD(2,2), &wsaDat) != 0)
    {
        SendMessage(hwnd, LOG_ADD, 0, (LPARAM)L"Winsock initialization failed");
        return;
    }

    SendMessage(hwnd, LOG_ADD, 0, (LPARAM)L"Done!\nCreating a socket... ");

    m_Socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (m_Socket == INVALID_SOCKET)
    {
        SendMessage(hwnd, LOG_ADD, 0, (LPARAM)L"Socket Creation failed");
        return;
    }

    SendMessage(hwnd, LOG_ADD, 0, (LPARAM)L"Done!\nRequesting Windows message-based notification of network events... ");

    if (WSAAsyncSelect(m_Socket, hwnd, WM_SOCKET, FD_CLOSE|FD_READ) != 0)
    {
        SendMessage(hwnd, LOG_ADD, 0, (LPARAM)L"WSAAsyncSelect failed");
        return;
    }

    /* More code */
}

.

int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmdLine, int nShowCmd)
{
    if(SUCCEEDED(CoInitialize(NULL)))
    {
        Game game;
        game.CreateResources(hInst);
        game.ShowMainScreen();
        ...
    }
}

void Game::CreateResources(HINSTANCE hInst)
{   
    m_hWnd = CreateWindowClass(hInst);
    pMessageLog = CreateMessageLog();
    pD2DResources = CreateD2DResources(m_hWnd);
    pWinsock = CreateWinsock();
    pWinsock->Initialize(m_hWnd);
}