Системное программирование в среде Windows
Шрифт:
/* Многопоточный сервер командной строки. Версия на основе именованных каналов. */
#include "EvryThng.h"
#include "ClntSrvr.h" /* Определения сообщений запроса и ответа. */
typedef struct { /* Аргумент серверного потока. */
HANDLE hNamedPipe; /* Экземпляр именованного канала. */
DWORD ThreadNo;
TCHAR TmpFileName[MAX_PATH]; /*
Имя временного файла. */
} THREAD_ARG;
typedef THREAD_ARG *LPTHREAD_ARG;
volatile static BOOL ShutDown = FALSE;
static DWORD WINAPI Server(LPTHREAD_ARG);
static DWORD WINAPI Connect(LPTHREAD_ARG);
static DWORD WINAPI ServerBroadcast(LPLONG);
static BOOL WINAPI Handler(DWORD);
static TCHAR ShutRqst[] = _T("$ShutDownServer");
_tmain(int argc, LPTSTR argv[]) {
/* Определение MAX_CLIENTS содержится в файле ClntSrvr.h. */
HANDLE hNp, hMonitor, hSrvrThread[MAXCLIENTS];
DWORD iNp, MonitorId, ThreadId;
LPSECURITY_ATTRIBUTES pNPSA = NULL;
THREAD_ARG ThArgs[MAXCLIENTS];
/* Обработчик управляющих сигналов консоли, используемый для остановки сервера. */
SetConsoleCtrlHandler(Handler, TRUE);
/* Периодически создавать имя широковещательного канала потока. */
hMonitor = (HANDLE)_beginthreadex(NULL, 0, ServerBroadcast, NULL, 0, &MonitorId);
/* Создать экземпляр канала и временный файл для каждого серверного потока. */
for (iNp = 0; iNp < MAX_CLIENTS; iNp++) {
hNp = CreateNamedPipe(SERVER_PIPE, PIPE_ACCESS_DUPLEX, PIPE_READMODE_MESSAGE | PIPE_TYPE_MESSAGE | PIPE_WAIT, MAXCLIENTS, 0, 0, INFINITE, pNPSA);
ThArgs[iNp].hNamedPipe = hNp;
ThArgs[iNp].ThreadNo = iNp;
GetTempFileName(_T("."), _T("CLP"), 0, ThArgs[iNp].TmpFileName);
hSrvrThread[iNp] = (HANDLE)_beginthreadex(NULL, 0, Server, &ThArgs[iNp], 0, &ThreadId);
}
/* Ждать завершения выполнения всех потоков. */
WaitForMultipleObjects(MAXCLIENTS, hSrvrThread, TRUE, INFINITE);
WaitForSingleObject(hMonitor, INFINITE);
CloseHandle(hMonitor);
for (iNp = 0; iNp < MAXCLIENTS; iNp++) {
/* Закрыть дескрипторы канала и удалить
временные файлы. */
CloseHandle(hSrvrThread[iNp]);
DeleteFile(ThArgs[iNp].TmpFileName);
}
_tprintf(_T("Серверный процесс завершил выполнение.\n"));
return 0;
}
static DWORD WINAPI Server(LPTHREAD_ARG pThArg)
/* Функция потока сервера; по одной для каждого потенциального клиента. */
{
HANDLE hNamedPipe, hTmpFile = INVALID_HANDLE_VALUE, hConTh, hClient;
DWORD nXfer, ConThId, ConThStatus;
STARTUPINFO StartInfoCh;
SECURITY_ATTRIBUTES TempSA = {sizeof(SECURITY_ATTRIBUTES), NULL, TRUE};
PROCESS_INFORMATION ProcInfo;
FILE *fp;
REQUEST Request;
RESPONSE Response;
GetStartupInfo(&StartInfoCh);
hNamedPipe = pThArg->hNamedPipe;
hTmpFile = CreateFile(pThArg->TmpFileName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, &TempSA, CREATE_ALWAYS, FILE_ATTRIBUTE_TEMPORARY, NULL);
while (!ShutDown) { /* Цикл соединений. */
/* Создать поток соединения; ждать его завершения. */
hConTh = (HANDLE)_beginthreadex(NULL, 0, Connect, pThArg, 0, &ConThId);
/* Ожидание соединения с клиентом и проверка флага завершения работы.*/
while (!ShutDown && WaitForSingleObject(hConTh, CS_TIMEOUT) == WAIT_TIMEOUT) { /* Пустое тело цикла. */ };
CloseHandle(hConTh);
if (ShutDown) continue; /*Флаг может быть установлен любым потоком.*/
/* Соединение существует. */
while (!ShutDown && ReadFile(hNamedPipe, &Request, RQ_SIZE, &nXfer, NULL)) {
/* Получать новые команды до отсоединения клиента. */
ShutDown = ShutDown || (_tcscmp(Request.Record, ShutRqst) == 0);
if (ShutDown) continue; /* Проверяется на каждой итерации. */
/* Создать процесс для выполнения команды. */
StartInfoCh.hStdOutput = hTmpFile;
StartInfoCh.hStdError = hTmpFile;
StartInfoCh.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
StartInfoCh.dwFlags = STARTF_USESTDHANDLES;
Поделиться:
Популярные книги
Предатель. Цена ошибки
Измена
Любовные романы:
современные любовные романы
5.75
рейтинг книги
Вечный. Книга V
5. Вечный
Фантастика:
боевая фантастика
попаданцы
рпг
5.00
рейтинг книги
Мимик нового Мира 13
12. Мимик!
Фантастика:
боевая фантастика
юмористическая фантастика
рпг
5.00
рейтинг книги
Идеальный мир для Лекаря 15
15. Лекарь
Фантастика:
боевая фантастика
юмористическая фантастика
аниме
5.00
рейтинг книги
Чужой ребенок
1. Чужие люди
Любовные романы:
современные любовные романы
6.25
рейтинг книги
Новый Рал 3
3. Рал!
Фантастика:
попаданцы
5.88
рейтинг книги
Кодекс Охотника. Книга XV
15. Кодекс Охотника
Фантастика:
попаданцы
аниме
5.00
рейтинг книги
Возвышение Меркурия. Книга 12
12. Меркурий
Фантастика:
героическая фантастика
попаданцы
аниме
5.00
рейтинг книги
Провинциал. Книга 5
5. Провинциал
Фантастика:
космическая фантастика
рпг
аниме
5.00
рейтинг книги
Польская партия
3. Фрунзе
Фантастика:
попаданцы
альтернативная история
5.25
рейтинг книги
Бальмануг. (Не) Любовница 1
3. Мир Десяти
Фантастика:
юмористическое фэнтези
попаданцы
5.00
рейтинг книги
Чиновникъ Особых поручений
6. Александр Агренев
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Последний попаданец 2
2. Последний попаданец
Фантастика:
юмористическая фантастика
попаданцы
рпг
7.50
рейтинг книги
Черный Маг Императора 7 (CИ)
7. Черный маг императора
Фантастика:
фэнтези
попаданцы
5.00