Why do I get the WSAENOTSOCK error in this code?

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?

Upvotes: 0

Views: 7665

Answers (1)

Remy Lebeau
Remy Lebeau

Reputation: 598174

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

Upvotes: 2

Related Questions