Click here to Skip to main content
15,867,568 members
Home / Discussions / C / C++ / MFC
   

C / C++ / MFC

 
Questionstandard way to parse command line from a string Pin
Ribhi Kamal27-Jun-11 8:59
professionalRibhi Kamal27-Jun-11 8:59 
AnswerRe: standard way to parse command line from a string [modified] Pin
CPallini27-Jun-11 9:48
mveCPallini27-Jun-11 9:48 
AnswerRe: standard way to parse command line from a string Pin
David Crow27-Jun-11 10:05
David Crow27-Jun-11 10:05 
AnswerRe: standard way to parse command line from a string Pin
Richard MacCutchan27-Jun-11 22:07
mveRichard MacCutchan27-Jun-11 22:07 
QuestionIO Completion Ports and windows sockets Pin
csrss27-Jun-11 7:19
csrss27-Jun-11 7:19 
AnswerRe: IO Completion Ports and windows sockets Pin
jschell27-Jun-11 8:14
jschell27-Jun-11 8:14 
GeneralRe: IO Completion Ports and windows sockets Pin
csrss27-Jun-11 8:44
csrss27-Jun-11 8:44 
AnswerRe: IO Completion Ports and windows sockets [modified] Pin
Mark Salsbery27-Jun-11 13:18
Mark Salsbery27-Jun-11 13:18 
I may not be following all your steps, but it appears all your threads end up waiting for socket accepts so everything is deadlocked.

Here's what I do...

Create a listener thread. Its job is to accept incoming connections and queue up the first completion job on the I/O completion port. I personally don't use AcceptEx anymore. I use a regular listener socket (bind()) and use an event (::WSAEventSelect(hListenSocket, hNetEvent, FD_ACCEPT);) to wake my listener thread when a connection request arrives. The listener thread proc just loops waiting on the event (and also a termination event for shutdown time). It looks like this:
DWORD CClientListener::ThreadProc()
{
    while (1)
    {
        #define EVENT_NET            0
        #define EVENT_TERMINATE        1
        HANDLE Events[] =
        {
            hNetEvent,
            hTerminateEvent
        };
        DWORD dwEventIndex = ::WaitForMultipleObjects(sizeof(Events) / sizeof(HANDLE),
                                                                                Events, FALSE, INFINITE);
        if (dwEventIndex == WAIT_FAILED)
        {
            break;
        }
        dwEventIndex -= WAIT_OBJECT_0;


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

        // Check if thread termination requested

        if (dwEventIndex == EVENT_TERMINATE)
        {
            break;
        }

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

        // Check if FD_ACCEPT socket notification

        if (dwEventIndex == EVENT_NET)
        {
            WSANETWORKEVENTS WsaNetworkEvents;
            if (0 == ::WSAEnumNetworkEvents(hListenSocket, hNetEvent, &WsaNetworkEvents)) //(resets hNetEvent)
            {
                if (WsaNetworkEvents.lNetworkEvents & FD_ACCEPT)
                {
                    OnAccept();
                }
            }
        }

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


    }  //while (1)

    return 0U;
}

OnAccept()
1) creates a socket for the connection using ::WSAAccept()
2) creates an object of a class representing a client connection and adds this object to a collection
3) associates the new socket with the completion port using ::CreateIoCompletionPort()
4) creates/initializes a custom overlapped structure
5) Queues up a receive operation on the completion port using WSARecv()

That's it. I don't go to another thread to do the accept or anything else. From my OnAccept() call onward, the completion port threads handle all I/O.

For the I/O completion port I use a thread class. I create a pool of threads of this class, generally two threads per processor core works well. Pointers to these objects are kept in a collection so I can queue up a shutdown thread command for each pool thread on the completion port at shutdown time. The thread proc simply loops, waiting on ::GetQueuedCompletionStatus(), and handling each queued completion command, whether it be a receive, send, or exit thread command (determined by an opcode in the custom overlapped struct). I generally use a request-reply protocol (because it's easy, although I have added some unidirectional communication at times) so each processed receive command queues up a send command, and each processed send command queues up a receive command, all re-using the same custom overlapped struct.


Make sense?

Note: In case you didn't know...It's a common sockets programming mistake to assume the number of bytes requested to send or receive will all be sent or received in one call. This applies to I/O completion ports as well. Be prepared to handle sending or receiving remaining bytes when a completion event occurs. I personally track this in the custom overlapped struct.
Mark Salsbery
Microsoft MVP - Visual C++

Java | [Coffee]
modified on Monday, June 27, 2011 7:41 PM

GeneralRe: IO Completion Ports and windows sockets Pin
csrss27-Jun-11 14:04
csrss27-Jun-11 14:04 
GeneralRe: IO Completion Ports and windows sockets Pin
Mark Salsbery27-Jun-11 14:13
Mark Salsbery27-Jun-11 14:13 
GeneralRe: IO Completion Ports and windows sockets Pin
csrss27-Jun-11 14:31
csrss27-Jun-11 14:31 
QuestionSOLVED MoveWindow dynamically - how to determine the destination? Pin
Vaclav_27-Jun-11 6:35
Vaclav_27-Jun-11 6:35 
AnswerRe: MoveWindow dynamically - how to determine the destination? Pin
Richard MacCutchan27-Jun-11 7:30
mveRichard MacCutchan27-Jun-11 7:30 
GeneralRe: MoveWindow dynamically - how to determine the destination? Pin
Albert Holguin27-Jun-11 8:19
professionalAlbert Holguin27-Jun-11 8:19 
GeneralRe: MoveWindow dynamically - how to determine the destination? Pin
Richard MacCutchan27-Jun-11 21:52
mveRichard MacCutchan27-Jun-11 21:52 
GeneralRe: MoveWindow dynamically - how to determine the destination? Pin
Albert Holguin28-Jun-11 3:36
professionalAlbert Holguin28-Jun-11 3:36 
AnswerRe: MoveWindow dynamically - how to determine the destination? Pin
Albert Holguin27-Jun-11 7:30
professionalAlbert Holguin27-Jun-11 7:30 
GeneralRe: MoveWindow dynamically - how to determine the destination? Pin
Vaclav_27-Jun-11 13:38
Vaclav_27-Jun-11 13:38 
GeneralRe: MoveWindow dynamically - how to determine the destination? Pin
Albert Holguin27-Jun-11 15:14
professionalAlbert Holguin27-Jun-11 15:14 
Questionlocalizing MFC feature pack (VS 2008) resources. Pin
kle8vi27-Jun-11 1:09
kle8vi27-Jun-11 1:09 
QuestionError while using A_StringFromGUID2 Pin
Pranit Kothari26-Jun-11 23:01
Pranit Kothari26-Jun-11 23:01 
AnswerRe: Error while using A_StringFromGUID2 Pin
Iain Clarke, Warrior Programmer26-Jun-11 23:19
Iain Clarke, Warrior Programmer26-Jun-11 23:19 
QuestionSetting Focus to a Dialog on Clicking it. [modified] Pin
pix_programmer26-Jun-11 22:48
pix_programmer26-Jun-11 22:48 
AnswerRe: Setting Focus to a Dialog on Clicking it. Pin
Iain Clarke, Warrior Programmer26-Jun-11 23:11
Iain Clarke, Warrior Programmer26-Jun-11 23:11 
GeneralRe: Setting Focus to a Dialog on Clicking it. Pin
pix_programmer26-Jun-11 23:18
pix_programmer26-Jun-11 23:18 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.