Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Запросы не попадают в Completion Port  (Прочитано 6572 раз)
0 Пользователей и 1 Гость смотрят эту тему.
Detsel
Гость
« : 24-10-2005 14:49 » 

Доброго времени суток. Такая проблема. Начал разрабатывать сервер на 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 соснах я плутаю. Клиент самый простой. И если ожидать данные от него синхронным методом, то они доходят. Заранее большое спасибо всем ответившим.
Записан
sss
Специалист

ru
Offline Offline

« Ответ #1 : 25-10-2005 07:58 » 

Покажи как реализована
Код:
serSock->AssociateSocketWithCompletionPort(clientSocket, serSock->m_hIOCP, (DWORD) lpPerHandleData))
Записан

while (8==8)
Detsel
Гость
« Ответ #2 : 26-10-2005 09:18 » 

Спасибо за ответ! Но я уже разобрался. Проблема была в моем неполном понимании работы Completion Port. Нужно было после принятия соединения с клиентом вызвать ф-ю WSARecv чтобы этот запрос поступил в очередь порта, и после получения данных от клиента ф-я GetQueuedCompletionStatus сработала. Еще раз спасибо.
Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines