Russian Qt Forum
Ноябрь 26, 2024, 11:57 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: самый простой многопоточный сервер на именованных каналах, пара вопросов.  (Прочитано 1390 раз)
libertas
Гость
« : Апрель 03, 2014, 14:26 »

Здравсвуйте,

я написал простой сервер, который для каждого клиента запускает отдельный поток: Клиент посылает сообщения, сервер на них отвечает. Клиенты и сервер общаются через экземпляры именованых каналов.

Вот основной код на сервере:

Код:
void MainWindow::on_Run_clicked()
{
    DWORD iNp;
    int MAX_CLIENTS = 20;
    ThreadArg* ThArgs[MAX_CLIENTS];
    HANDLE hT[MAX_CLIENTS];
    for (iNp = 0; iNp < MAX_CLIENTS; iNp++){
        hNp = CreateNamedPipe(PIPE_NAME,
                              PIPE_ACCESS_DUPLEX,
                              PIPE_READMODE_MESSAGE | PIPE_TYPE_MESSAGE | PIPE_WAIT,
                              PIPE_UNLIMITED_INSTANCES,
                              0,
                              0,
                              INFINITE,
                              0);
        if (hNp != INVALID_HANDLE_VALUE){
            MessageBox(0, L"Named pipe is created", L"Info", MB_OK);
        }
        if (ConnectNamedPipe(hNp, 0) == 0){
            MessageBox(0, L"ConnectNamedPipe failed with with error", L"Info", MB_OK);
            CloseHandle(hNp);
        }
        ThArgs[iNp] = new ThreadArg(hNp, iNp);
        hT[iNp] = CreateThread(0, 0, ThreadFunction, ThArgs[iNp], 0, 0);
        QObject::connect(ThArgs[iNp], SIGNAL(needWriteRequest(QString)), this, SLOT(paintRequest(QString)), Qt::BlockingQueuedConnection);

    }
    WaitForMultipleObjects(iNp, hT, TRUE, INFINITE);
    for (int i =0; i < iNp; i++){
        CloseHandle(hT[i]);
        //DisconnectNamedPipe(ThArgs[i]->hNamedPipe);
    }
}

DWORD WINAPI MainWindow::ThreadFunction(LPVOID threadArg){
    ThreadArg* p = static_cast<ThreadArg*>(threadArg);
    DWORD Read;
    DWORD Written;
    char Buf[256];
    char BufWr[256];

    if (ReadFile(p->hNamedPipe, Buf, 256, &Read, 0) <= 0){
        MessageBox(0, L"ReadFile failed with error", L"Info", MB_OK);
        CloseHandle(p->hNamedPipe);
    }
    QString qstr = QString::fromUtf8(Buf);
    emit p->needWriteRequest(qstr);

    QString ans = "answer";
    strcpy(BufWr, ans.toLocal8Bit().data());
    WriteFile(p->hNamedPipe, BufWr, sizeof(BufWr), &Written, 0);
    delete p;
    return 0;
}

Вот основной код на клиенте:

Код:
void MainWindow::on_CreateConnection_clicked()
{
    if (WaitNamedPipe(PIPE_NAME, NMPWAIT_WAIT_FOREVER) == 0) {
        MessageBox(0, L"WaitNamedPipe failed with error", L"Info", MB_OK);
        return;
    }

    if ((hNp = CreateFile(PIPE_NAME,
                          GENERIC_READ | GENERIC_WRITE, 0,
                          (LPSECURITY_ATTRIBUTES) NULL, OPEN_EXISTING,
                          FILE_ATTRIBUTE_NORMAL,
                          (HANDLE) NULL)) == INVALID_HANDLE_VALUE){
        MessageBox(0, L"CreateFile failed with error", L"Info", MB_OK);
    }

    DWORD Written;
    char BufWr[256];
    QString qstr = "request";
    strcpy(BufWr, qstr.toLocal8Bit().data());
    if (WriteFile(hNp, BufWr, sizeof(BufWr), &Written, NULL) == 0)
    {
        MessageBox(0, L"WriteFile failed with error", L"Info", MB_OK);
        CloseHandle(hNp);
        return;
    }
    DWORD Read;
    char Buf[256];
    if (ReadFile(hNp, Buf, 256, &Read, 0) <= 0){
        MessageBox(0, L"ReadFile failed with error", L"Info", MB_OK);
        CloseHandle(hNp);
        return;
    }
    QString qstrAns = QString::fromUtf8(Buf);
    ui->label->setText(qstrAns);
}

Проблема в том, что обмен сервер зависает в конце. Сообщения посылаются, но сервер подвисает.
И ещё. Мне нужно, чтоб клиент посылал запросы серверу периодически, а не один раз как у меня.
Как это можно исправить?

Спасибо.
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.044 секунд. Запросов: 20.