Название: самый простой многопоточный сервер на именованных каналах, пара вопросов.
Отправлено: 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); } Проблема в том, что обмен сервер зависает в конце. Сообщения посылаются, но сервер подвисает. И ещё. Мне нужно, чтоб клиент посылал запросы серверу периодически, а не один раз как у меня. Как это можно исправить? Спасибо.
|