Question : WSAEventSelect returns err WSAENOTSOCK

I have the following code, which basically does: socket();bind();listen();WSAEventSelect();

ALL i want to do is to get events when i recieve TCP message, when client call connect() or when a socket as been closed.

The simple call to WSAEventSelect returns err WSAENOTSOCK.
Why ?

code bellow:
// server.cpp : Defines the entry point for the application.
//

//#include "stdafx.h"
//#include

//#include "winsock.h"
#include "winsock2.h"
#include "stdio.h"

enum {
    INIT_FAILED = -1,
    INIT_STRTUP_FAILED = -2,
    ACCEPT_FAILED = -3
};

#define INPUT_BUFFER_SIZE  1000
//TCHAR InputBuffer [INPUT_BUFFER_SIZE];
char InputBuffer [INPUT_BUFFER_SIZE];

#define NUM_OF_SOCKETS  5
SOCKET sock;

SOCKET SockQueue [NUM_OF_SOCKETS];
int SockQueueHead = 0;

void Error (const char *str, ...)
{
    #define BUFF_LEN 255
    char buff [BUFF_LEN];
    va_list arg;

    if (strlen (str) > BUFF_LEN) {
        MessageBox (NULL, "could not allocate buffer for error message", NULL, MB_OK);
        return;
    }

    va_start(arg, str);
    wvsprintf (buff, str, arg);
    va_end(arg);

    MessageBox (NULL, buff, NULL, MB_OK);
}


int Init_WSAStartup(void)
{
    WSADATA wsaData;

    // initiates use of DLL
    if (int i = WSAStartup (MAKEWORD(1,1), &wsaData)) {
        Error ("Socket start-up failed");
        return i;
    }
    if (LOBYTE(wsaData.wVersion) !=1 || HIBYTE(wsaData.wVersion) !=1) {
        Error ("couldn't agree on socket lib version");
        return -1;
    }
    return 0;
}

int Init (void)
{
    if (Init_WSAStartup()) return INIT_STRTUP_FAILED; //do this per process

    return 0;
}

void SocketCleanup (SOCKET s)
{
    int rslt;
    HWND foo = NULL;

    WSAAsyncSelect (s, foo, 1, FD_CLOSE);
    //disable functionality of socket
    shutdown (s, SD_SEND); //SD_SEND declared in winsock2.h as 0x1
    //here i have to insert code to wait for FD_CLOSE
    rslt = recv (s, InputBuffer , sizeof (InputBuffer ), 0);
    while (!((rslt==0) || (rslt==SOCKET_ERROR))) {
        rslt = recv (s, InputBuffer , sizeof (InputBuffer ), 0);
    }
    closesocket (s);

    // remove dll from memory.
    if (WSACleanup () == SOCKET_ERROR) //for each call to WSASrartup, a call to WSACleanup must be issued
        Error ("socket clean-up fail");  
}

void Cleanup (void)
{
    SocketCleanup (sock);
}

int MarkSocketAsBlocking (SOCKET s)
{
    u_long argp = 0L;

    WSAAsyncSelect(s, NULL, 1,0); //disable Async function - last parameter is 0
    //WSAEventSelect(s, NULL, 0);  //disable Event function - last parameter is 0
    //ioctlsocket (s, FIFOBIO, &argp);
    return 0;
}


int MarkSocketAsNonblocking (SOCKET s)
{
    u_long argp = 1L;

    ioctlsocket (s, FIONBIO, &argp); //FIFONBIO defined as 1 in winsock.dll
    return 0;
}


/*int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     int       nCmdShow)
*/
int main ()
{
    SOCKADDR_IN local_sin;
    char hostname [100];
    HOSTENT *HostEnt;
      //int  nNumBytes;
    int err;
   
SOCKET NewSock;

    if (Init ()) return INIT_FAILED;
 
    if ((sock = socket (AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) {
        Error ("error %d while openning socket\n", err = WSAGetLastError());
        SocketCleanup (sock);
        return err;
    }


    gethostname(hostname, sizeof (hostname));
    HostEnt = gethostbyname (hostname);
    if (HostEnt == NULL) {
        Error ("error %d from gethostbyname\n", err = WSAGetLastError());
        SocketCleanup (sock);
        return err;
    }

   
    local_sin.sin_family = AF_INET;
    local_sin.sin_port = 10101;
    //local_sin.sin_addr.s_addr = INADDR_ANY;
    memcpy( (LPSTR)&(local_sin.sin_addr), HostEnt->h_addr, HostEnt->h_length);
    if (bind (sock, (const struct sockaddr *) &local_sin, sizeof (local_sin))) {
        Error ("error %d while bind number to socket\n", err = WSAGetLastError());
        SocketCleanup (sock);
        return err;
    }

    if (listen (sock, NUM_OF_SOCKETS)) { // it will be easer to handle just 1 at the first version
        Error ("error %d socket listen\n", err = WSAGetLastError());
        SocketCleanup (sock);
        return err;
    }

    //MarkSocketAsNonblocking (sock);

    WSAEVENT hEvent; //?? init to null ??
    if (WSAEventSelect (sock, hEvent, (long)(FD_READ|FD_WRITE|FD_ACCEPT|FD_CLOSE))) { //FD_CLOSE ?
        Error ("error %d in WSAEventSelect\n", err = WSAGetLastError());
        switch  (err){
        case WSANOTINITIALISED:
            Error ("WSANOTINITIALISED");
            break;
        case WSAENETDOWN:
            Error ("WSAENETDOWN");
            break;
        case WSAEINPROGRESS:
            Error ("WSAEINVAL");
            break;
        case WSAENOTSOCK:
            Error ("WSAENOTSOCK");
            break;
        case WSAEINVAL :
            Error ("WSAEINVAL ");
            break;
        default:
            Error ("default");
        }

  //*/
        // what tod do here ??
        return err;
    }


    WaitForMultipleObjects((DWORD)1, &hEvent, FALSE, INFINITE);
    //struct sockaddr addr;
    //int addrlen;

    //SockQueue[SockQueueHead++] = accept(sock, &addr, &addrlen);
    //if ( SockQueue[SockQueueHead - 1] == SOCKET_ERROR) {      
    NewSock = accept(sock, NULL /*&addr*/, NULL /*&addrlen*/);
    if ( NewSock == SOCKET_ERROR) {      
                  Error ("error %d socket accept\n", err = WSAGetLastError());
                  SocketCleanup (sock);
                  return err;
      }
            
    //Error ("%d %lx %lx", x, &InputBuffer, &InputBuffer[1000]); ??
    recv (NewSock, InputBuffer, sizeof (InputBuffer), 0);
    Error ("%s", InputBuffer);
   
    Cleanup ();
      return 0;
}

Answer : WSAEventSelect returns err WSAENOTSOCK

Hi,


the answer is simply that you need to create an event to use in the WSAEventSelect call.

instead of

WSAEVENT hEvent;

try

    WSAEVENT hEvent=CreateEvent(0,0,0,0);

and everything should be ok.

regards,
Mike.
Random Solutions  
 
programming4us programming4us