Доброго времени суток. Такая проблема. Начал разрабатывать сервер на Completion портах. Перечитал кучу всего, разобрался вроде как, сел писать. Накидал небольшой сервер и теперь пытаюсь посылать данные от клиента. Клиент с сервером соединяются, данные от клиента уходят, но вот на сервер так и не доходят, то есть функция GetQueuedCompletionStatus не возвращает управление. Я уже не знаю куда копать. То ли лыжи не едут, то ли ...
Сервер
    //Создаем порт завершения в/в
    m_hIOCP = CreateIoCompletionPort(INVALID_HANDLE_VALUE,
                    NULL,
                    (ULONG_PTR)0,
                    0);
        .....................................................
    //Создаем рабочий поток, который будет обрабатывать запросы поступающие в порт в/в
    if (CreateThread( 
            NULL,                       // no security attribute 
            0,                          // default stack size 
            (LPTHREAD_START_ROUTINE) WorkerThread, 
            (LPVOID) this,    // thread parameter 
            0,                          // not suspended 
            &dwThreadId)      // returns thread ID 
            == NULL)
     
        return ERROR_CREATING_WORKER_THREAD;
         ......................................................
        //Создаем серверный сокет, который будет ожидать подключения
    m_serverSocket = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, WSA_FLAG_OVERLAPPED);
    //Инициализируем адрес с которого ожидать подключения клиентов
    localAdr.sin_family = AF_INET;
    localAdr.sin_port = htons( m_iPortNum ) ;
    localAdr.sin_addr.s_addr = htonl( INADDR_ANY );
    
    //Привязываем серверный сокет к адресу определнному выше
    if (bind(m_serverSocket,(struct sockaddr*) &localAdr, sizeof(localAdr))!=0)
        return ERROR_BIND;
    //Ставиим сокет сервера в режим ожидания подключения от клиентов
    if (listen(m_serverSocket, 100) != 0)
        return ERROR_LISTEN;
    //Запускаем поток, который будет обрабатывать подключения от клиентов
    m_hAcceptThread = CreateThread( 
            NULL,                       // no security attribute 
            0,                          // default stack size 
            (LPTHREAD_START_ROUTINE) AcceptThread, 
            (LPVOID) this,    // thread parameter 
            0,                          // not suspended 
            &dwThreadId);      // returns thread ID 
    if (m_hAcceptThread == NULL) 
        return ERROR_CREATING_ACCEPT_THREAD;
Поток AcceptThread:
    SOCKET clientSocket = INVALID_SOCKET;
    CServerSocket* serSock = (CServerSocket*)lpvParam;
    struct sockaddr_in clientAdr;
    int adrlen = sizeof(clientAdr);
    LPPER_HANDLE_DATA lpPerHandleData;
    while(1)
    {        
        //Ожидаем подключения клиента
        clientSocket = WSAAccept(serSock->m_serverSocket, (struct sockaddr *)&clientAdr, (int*) &adrlen, NULL, NULL);
         if (clientSocket == INVALID_SOCKET) 
        {
            continue;
        }
        //Инициализируем структуру PER_HANDLE_DATA
        lpPerHandleData = (LPPER_HANDLE_DATA) GlobalAlloc(GPTR, sizeof(PER_HANDLE_DATA));
        if (lpPerHandleData == NULL)
        {
            continue;
        }
        lpPerHandleData->clientSocket = clientSocket;
        lpPerHandleData->clientAdr = clientAdr;
        if (!serSock->AssociateSocketWithCompletionPort(clientSocket, serSock->m_hIOCP, (DWORD) lpPerHandleData))
        {
            GlobalFree(lpPerHandleData);
            closesocket(clientSocket);
            continue;
        }
    }
Поток WorkerThread:
    CServerSocket* serSock = (CServerSocket*)lpvParam;
    DWORD dwBytesTransferred = 0;
    LPPER_HANDLE_DATA lpPerHandleData;
    LPPER_IO_OPERATION_DATA lpPerIoData = NULL;
    BOOL retIOCPValue;
    while (1)
    {
        retIOCPValue = GetQueuedCompletionStatus(
                        serSock->m_hIOCP,
                        &dwBytesTransferred ,
                        (PULONG_PTR)&lpPerHandleData,
                        (LPOVERLAPPED*) &lpPerIoData,
                        INFINITE);
        if (retIOCPValue == WAIT_TIMEOUT || retIOCPValue == 0)
        {
            // Operation failed
            continue;
        }
  
    
    switch (lpPerIoData->OperationCode)
    {
        .............................
        }
     }
И вот в этих 3 соснах я плутаю. Клиент самый простой. И если ожидать данные от него синхронным методом, то они доходят. Заранее большое спасибо всем ответившим.