CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 14 of 14
  1. #1
    Join Date
    Nov 2001
    Location
    Beijing, China
    Posts
    69

    WSAEnumNetworkEvents

    Hi,


    Could anyone tell me how to use WSAEnumNetworkEvents? My program is a TCP server, I hope to be notified when the tcp client closes, so that I could close that connection ASAP.


    Many thanks.


    connie

  2. #2
    Join Date
    Dec 2002
    Location
    St.Louis MO, USA
    Posts
    672
    // WSAEnumNetworkEvents copy the actual event into WSANETWORKEVENTS structure this function receive a socket and its associated event as parameter
    WSAEnumNetworkEvents(ptrSock->SocketArray[Index],ptrSock->EventArray[Index],&NetworkEvents);

    if(NetworkEvents.lNetworkEvents==FD_ACCEPT)
    // if WSANETWORKEVENTS structure's INetworkEvents equals to FD_ACCEPT then it means new socket connection request arrive
    {
    // The iErrorCode parameter is an array of error codes
    // associated with the events in lNetworkEvents. For each
    // network event type, there is a special event index
    // similar to the event type names "except for an additional
    // _BIT" string appended to the event name. For example,
    // for the FD_READ event type, the index identifier for
    // the iErrorCode array is named FD_READ_BIT.
    // for the FD_ACCEPT event type, the index identifier for
    // the iErrorCode array is named FD_ACCEPT_BIT.

    if(NetworkEvents.iErrorCode[FD_ACCEPT_BIT]!=0)
    {
    break;
    }
    // If no error occor then
    // On FD_ACCEPT event we create a new client socket and pass
    // it in accept function.
    Ptrnewsock->S=accept(ptrSock->SocketArray[Index],NULL,NULL);
    }
    else if(NetworkEvents.lNetworkEvents==FD_READ)
    // if WSANETWORKEVENTS structure's INetworkEvents equals to
    //FD_READ
    // then it means Data is available for read
    {
    if(NetworkEvents.iErrorCode[FD_READ_BIT]!=0)
    // checking for any error
    { break;
    }
    ptrSock->Recv((LPVOID)&ptrSock->SocketArray[Index]);
    // If no error occor then calling Recv function for receiving actual data and further processing
    }



    In FD_CLOSE event you should close that socket
    A Person who is polite is given goodness and a person who is away from Politeness is away from Goodness.

    NAUMAAN

  3. #3
    Join Date
    Nov 2001
    Location
    Beijing, China
    Posts
    69
    Thank you very much for your kind reply and sorry for the delay (I was on a business trip).

    I tried WSAEnumNetworkEvents, but failed. Because of the .h file. I am using afxsock.h. WSAEnumNetworkEvents requires winsock2.h. Is there any way that I can use with afxsock.h, so that I may not change a lot of my code?

    By the way, is there any better way than WSAEnumNetworkEvents to detect the connection was reset by the remote side?



    connie

  4. #4
    Join Date
    Nov 2001
    Location
    Beijing, China
    Posts
    69

    Question

    Hi,

    I changed to use "winsock2.h", the program can run.

    But I still can not detect tcp client's disconnect. My program is a TCP server. Where should I put WSAEnumNetworkEvents()? Should I use OnTimer()?


    Thanks.

    connie

  5. #5
    Join Date
    Dec 2002
    Location
    St.Louis MO, USA
    Posts
    672
    Use the following code to detect closing of a socket

    else if(NetworkEvents.lNetworkEvents==FD_CLOSE) // if WSANETWORKEVENTS structure's INetworkEvents equals to FD_CLOSE
    // then it means Socket is closed
    {
    if(NetworkEvents.iErrorCode[FD_CLOSE_BIT]!=0 ) // checking for any error
    {
    break;
    }
    closesocket(ptrSock->SocketArray[Index]);
    // if no error occor then closing the socket
    // Index variable contain the index of socket and event objects
    WSACloseEvent(ptrSock->EventArray[Index]); // Closing the event object

    }

    u did not require any timer because when u r waiting for multiple events, this close event will also handled in that thread.

    I think u r using WSAEventSelect model of socket so u have only this choice to detect socket events.
    A Person who is polite is given goodness and a person who is away from Politeness is away from Goodness.

    NAUMAAN

  6. #6
    Join Date
    Nov 2001
    Location
    Beijing, China
    Posts
    69
    Hi,

    Thanks for your reply.

    I used select ( 0, &fdset, NULL, NULL, &timeout ) in SocketCheck() to detect client's connection. My code is like this:

    while(b_ServerStop!=true)
    {
    WSAEnumNetworkEvents(client,myevent,&NetworkEvents);

    if(NetworkEvents.lNetworkEvents==FD_CLOSE)
    {
    closesocket(client);
    }

    if (pdlg_sevr->SocketCheck(server,SC_READ))
    {
    client=accept(server,
    (struct sockaddr*)&from,&fromlen);
    ...............
    }
    }

    I can not detect client's disconnection.

    Could you please give me some advice?


    connie

  7. #7
    Join Date
    Dec 2002
    Location
    St.Louis MO, USA
    Posts
    672
    can u explain which socket model u r using
    Try to use like this

    if(NetworkEvents.lNetworkEvents==FD_ACCEPT)
    {
    if (pdlg_sevr->SocketCheck(server,SC_READ))
    {
    client=accept(server,
    (struct sockaddr*)&from,&fromlen);
    ...............
    // After acceptance of socket call WSAEventSelect function on newly
    //accepted socket.
    WSAEventSelect(client,newevent,FD_READ | FD_WRITE | FD_CLOSE);
    // Here newevent is a newly created event by WSACreateEvent() function
    // I m using WSAEventSelect Model
    }

    }
    A Person who is polite is given goodness and a person who is away from Politeness is away from Goodness.

    NAUMAAN

  8. #8
    Join Date
    Nov 2001
    Location
    Beijing, China
    Posts
    69
    Hi,

    Thank you.

    I changed my code according to your code. But it still does not work.

    I used
    SOCKET client, server;
    select();

    not WSAEVENTSELECT(). Actually I can not detect connection event with WSAEVENTSELECT(). How is that? Is that I need to include some other .h file?


    connie

  9. #9
    Join Date
    Dec 2002
    Location
    St.Louis MO, USA
    Posts
    672
    Paste your Listen , Accept and Connect code then i can give u proper solution.

    because WSAEnumNetworkEvent function is used to handle WSAEventSelect Model Properly.
    So if u r using select function then it did not take Event object so attach your code in reply.
    A Person who is polite is given goodness and a person who is away from Politeness is away from Goodness.

    NAUMAAN

  10. #10
    Join Date
    Nov 2001
    Location
    Beijing, China
    Posts
    69
    Hi,

    Thanks for your kind help.

    my code is:

    WSADATA wsaData;
    sockaddr_in local;
    int wsaret=WSAStartup(0x101,&wsaData);
    if(wsaret!=0)
    {
    return -1;
    }
    local.sin_family=AF_INET;
    local.sin_addr.s_addr=INADDR_ANY;
    local.sin_port=htons((u_short)sevr_port);
    server=socket(AF_INET,SOCK_STREAM,0);
    if(server==INVALID_SOCKET)
    {
    WSACleanup ( );
    AfxMessageBox("Create Server socket failed!");
    return -1;
    }
    if(bind(server,(sockaddr*)&local,sizeof(local))!=0)
    {
    closesocket ( server );
    WSACleanup ( );
    AfxMessageBox("Server socket bind failed!");
    return -1;
    }
    if(listen(server, ACCEPT_QUEUE)!=0)
    {
    closesocket ( server );
    WSACleanup ( );
    AfxMessageBox("Server socket listen failed!");
    return -1;
    }

    SOCKET client;
    sockaddr_in from;
    int fromlen=sizeof(from);
    WSAEVENT myevent,newevent;
    WSANETWORKEVENTS NetworkEvents;

    while(b_ServerStop!=true)
    {
    WSAEnumNetworkEvents(client,myevent,&NetworkEvents);
    WSAEventSelect(client,newevent,FD_READ | FD_WRITE | FD_CLOSE);

    if(NetworkEvents.lNetworkEvents==FD_ACCEPT)
    {

    if (pdlg_sevr->SocketCheck(server,SC_READ))
    {
    client=accept(server,
    (struct sockaddr*)&from,&fromlen);
    ........
    }
    }
    }


    connie

  11. #11
    Join Date
    Dec 2002
    Location
    St.Louis MO, USA
    Posts
    672
    Try to use ur code like this
    --------------------------------------------------------------------------------------------------------
    --------------------------------------------------------------------------------------------------------
    WSAEVENT EventArray[64];
    SOCKET SockArray[64];
    UINT EventTotal=0;
    WSADATA wsaData;
    sockaddr_in local;
    int wsaret=WSAStartup(MAKEWORD(2,2),&WsaData);
    if(wsaret!=0)
    {
    return -1;
    }
    local.sin_family=AF_INET;
    local.sin_addr.s_addr=INADDR_ANY;
    local.sin_port=htons((u_short)sevr_port);
    server=socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if(server==INVALID_SOCKET)
    {
    WSACleanup ( );
    AfxMessageBox("Create Server socket failed!");
    return -1;
    }
    if(bind(server,(sockaddr*)&local,sizeof(local))!=0)
    {
    closesocket ( server );
    WSACleanup ( );
    AfxMessageBox("Server socket bind failed!");
    return -1;
    }

    //****************************************************************
    WSAEVENT newserverevent; // Event object to attach with listening socket
    if((newserverevent=WSACreateEvent())==WSA_INVALID_EVENT) // Create a new
    // event object and assign to newevent
    return -1; // if event cannot created then return -1
    if(WSAEventSelect(server,newserverevent,FD_ACCEPT | FD_CLOSE)
    ==SOCKET_ERROR)
    // Calling WSAEventSelect function on
    // Listening socket and newevent to attach
    // Accept and close events
    return -1; // If function failes then return -1

    EventArray[EventTotal]=newserverevent;
    SockArray[EventTotal]=server;
    EventTotal++;
    //***************************************************************

    if(listen(server, ACCEPT_QUEUE)!=0)
    {
    closesocket ( server );
    WSACleanup ( );
    AfxMessageBox("Server socket listen failed!");
    return -1;
    }

    //***************************************************************
    //***************************************************************

    SOCKET client;


    WSANETWORKEVENTS NetworkEvents;
    UINT Index,ret;
    while(b_ServerStop!=true)
    {

    ret=WSAWaitForMultipleEvents(EventsTotal,EventArray,FALSE,
    WSA_INFINITE,FALSE);
    if ((ret != WSA_WAIT_FAILED) && (ret != WSA_WAIT_TIMEOUT))
    {
    Index=ret-WSA_WAIT_EVENT_0;
    for(int i=Index;i<EventsTotal;i++)
    {

    Index=WSAWaitForMultipleEvents(1,&EventArray[i],TRUE,1000,FALSE);
    if ((Index != WSA_WAIT_FAILED) && (Index != WSA_WAIT_TIMEOUT))
    {
    Index=i;
    WSAEnumNetworkEvents(SocketArray[Index],EventArray[Index]
    ,&NetworkEvents);
    if(NetworkEvents.lNetworkEvents==FD_ACCEPT)
    {
    if(NetworkEvents.iErrorCode[FD_ACCEPT_BIT]!=0)
    {
    break;
    }
    // If no error occor then
    // On FD_ACCEPT event we create a new client socket and
    // pass it in accept function.
    // Accept function extract that newly connected socket from que
    // after accept function we call WSAEventSelect on
    // newly accepted socket
    // to get its events in this while loop
    WSAEVENT newclientevent; // Creating a new WSAEVENT object
    newclientevent=WSACreateEvent();
    client=accept(SocketArray[Index],NULL,NULL);
    // CAlling WSAEventSelect function on newly accepted socket to
    // receive its READ,WRITE AND CLOSE Events in this thread
    WSAEventSelect(client,neweclientvent,FD_READ | FD_WRITE |
    FD_CLOSE);
    // FD_ACCEPT event occors only on server end so i m inserting newly
    // accepted socket and its evnet into listening socket's event and
    // socket arrays
    // Inserting new socket into socket arrray
    SocketArray[EventsTotal]=client;
    EventArray[EventsTotal]=newclientevent; // Inserting new event
    //associated with new socket
    // into event array
    EventsTotal++; // Increasing the EventTotal variable
    }
    else if(NetworkEvents.lNetworkEvents==FD_READ)
    {
    // YOUR socket data read code
    }
    else if(NetworkEvents.lNetworkEvents==FD_CLOSE)
    {
    // YOUR socket close code
    }
    ........
    }
    }
    }
    }


    --------------------------------------------------------------------------------------------------------
    --------------------------------------------------------------------------------------------------------
    Last edited by ABDULNAUMAN; July 20th, 2004 at 12:12 AM.
    A Person who is polite is given goodness and a person who is away from Politeness is away from Goodness.

    NAUMAAN

  12. #12
    Join Date
    Nov 2001
    Location
    Beijing, China
    Posts
    69
    Hi,

    Thanks for your great help!

    I tried. FD_ACCEPT works well. But FD_CLOSE does not. I have a simple VB program acts as TCP client, when I close that program, the TCP server in VC receives an event, but the NetworkEvents.INetworkEvents=0, so it can not close the socket. I noticed that FD_ACCEPT means NetworkEvents.INetworkEvents=8.
    I guess for FD_CLOSE, NetworkEvents.INetworkEvents=32.

    I wonder why NetworkEvents.INetworkEvents value is incorrect when the tcp client quit?

    connie

  13. #13
    Join Date
    Dec 2002
    Location
    St.Louis MO, USA
    Posts
    672
    Have u tried the Accept portion just like my code

    there are few steps.

    1: Create a new WSAEVEVENT
    WSAEVENT newclientevent; // Creating a new WSAEVENT object
    newclientevent=WSACreateEvent();

    2: Call Accept function and assign newly accepted socket to your client socket
    SOCKET client=accept(serversock,NULL,NULL);

    3: attaching the newclientevent with newly accepted socket for receiving its events
    WSAEventSelect(client,neweclientvent,FD_READ | FD_WRITE |
    FD_CLOSE);

    4: inserting the newly accepted socket into socket array and inserting newclientevent into Event array and increase EventTotal variable
    if u did not do the forth step then u cannot provide service to newly accepted socket .

    SocketArray[EventsTotal]=client;
    EventArray[EventsTotal]=newclientevent;
    EventTotal++;









    *****************************************************************
    if(NetworkEvents.lNetworkEvents==FD_ACCEPT)
    {
    if(NetworkEvents.iErrorCode[FD_ACCEPT_BIT]!=0)
    {
    break;
    }
    // If no error occor then
    // On FD_ACCEPT event we create a new client socket and
    // pass it in accept function.
    // Accept function extract that newly connected socket from que
    // after accept function we call WSAEventSelect on
    // newly accepted socket
    // to get its events in this while loop
    WSAEVENT newclientevent; // Creating a new WSAEVENT object
    newclientevent=WSACreateEvent();
    client=accept(SocketArray[Index],NULL,NULL);
    // CAlling WSAEventSelect function on newly accepted socket to
    // receive its READ,WRITE AND CLOSE Events in this thread
    WSAEventSelect(client,neweclientvent,FD_READ | FD_WRITE |
    FD_CLOSE);
    // FD_ACCEPT event occors only on server end so i m inserting newly
    // accepted socket and its evnet into listening socket's event and
    // socket arrays
    // Inserting new socket into socket arrray
    SocketArray[EventsTotal]=client;
    EventArray[EventsTotal]=newclientevent; // Inserting new event
    //associated with new socket
    // into event array
    EventsTotal++; // Increasing the EventTotal variable
    }

    *****************************************************************
    A Person who is polite is given goodness and a person who is away from Politeness is away from Goodness.

    NAUMAAN

  14. #14
    Join Date
    Nov 2001
    Location
    Beijing, China
    Posts
    69

    Re: WSAEnumNetworkEvents

    Hello,

    I tested again and found that while(b_ServerStop!=true)
    {
    ......
    }

    in my TCP server application sometimes goes into infinite loop.

    I tested with my code and a sample VC++ TCP client application. I kept my TCP server application running. The client would do connect(), send(), shutdown(), step by step, then I closes this client application. Then I restarted it.

    I found that my application worked well for the first time the client connected,but when the client connected for the second time,my application continuously receive network event after client connect(),NetworkEvents.lNetworkEvents=8, then goes into infinite loop.

    How is that? Could you please give me a piece of advice?

    Thanks and best regards,
    connie

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured