// Программа из конспекта "Системное программное обеспечение" // Именованные каналы в Windows // стр. ?? // Приложение NAMEDPIPESERVER (серверное приложение) // Демонстрация использования именованных каналов // для передачи данных между процессами #define _CRT_SECURE_NO_WARNINGS #include #include #include int main() { // Флаг успешного создания канала BOOL fConnected; // Идентификатор канала Pipe HANDLE hNamedPipe; // Имя создаваемого канала Pipe LPSTR lpszPipeName = (LPSTR)"\\\\.\\pipe\\$MyPipe$"; // Буфер для передачи данных через канал char szBuf[512]; // Количество байт данных, принятых через канал DWORD cbRead; // Количество байт данных, переданных через канал DWORD cbWritten; DWORD total = 0; // буфер для сообщения об ошибке, результата char message[80] = { 0 }; // Дескриптор файла FILE* hdl; printf("Named pipe server demo\n"); // Создаем канал Pipe, имеющий имя lpszPipeName hNamedPipe = CreateNamedPipe( lpszPipeName, PIPE_ACCESS_DUPLEX, PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, PIPE_UNLIMITED_INSTANCES, 512, 512, 5000, NULL); // Если возникла ошибка, выводим ее код и зваершаем работу приложения if (hNamedPipe == INVALID_HANDLE_VALUE) { fprintf(stdout, "CreateNamedPipe: Error %ld\n", GetLastError()); _getch(); return 0; } // Выводим сообщение о начале процесса создания канала fprintf(stdout, "Waiting for connect...\n"); // Ожидаем соединения со стороны клиента fConnected = ConnectNamedPipe(hNamedPipe, NULL); // При возникновении ошибки выводим ее код if (!fConnected) { switch (GetLastError()) { case ERROR_NO_DATA: fprintf(stdout, "ConnectNamedPipe: ERROR_NO_DATA"); _getch(); CloseHandle(hNamedPipe); return 0; break; case ERROR_PIPE_CONNECTED: fprintf(stdout, "ConnectNamedPipe: ERROR_PIPE_CONNECTED"); _getch(); CloseHandle(hNamedPipe); return 0; break; case ERROR_PIPE_LISTENING: fprintf(stdout, "ConnectNamedPipe: ERROR_PIPE_LISTENING"); _getch(); CloseHandle(hNamedPipe); return 0; break; case ERROR_CALL_NOT_IMPLEMENTED: fprintf(stdout, "ConnectNamedPipe: ERROR_CALL_NOT_IMPLEMENTED"); _getch(); CloseHandle(hNamedPipe); return 0; break; default: fprintf(stdout, "ConnectNamedPipe: Error %ld\n", GetLastError()); _getch(); CloseHandle(hNamedPipe); return 0; break; } CloseHandle(hNamedPipe); _getch(); return 0; } // Выводим сообщение об успешном создании канала fprintf(stdout, "\nConnected. Waiting for command...\n"); // Цикл получения команд через канал while (1) { total = 0; // Получаем очередную команду через канал Pipe if (ReadFile(hNamedPipe, szBuf, 512, &cbRead, NULL)) { // Выводим принятую команду на консоль printf("Received: %s\n", szBuf); // Если пришла команда "exit", завершаем работу приложения if (!strcmp(szBuf, "exit")) { WriteFile(hNamedPipe, szBuf, strlen(szBuf) + 1, &cbWritten, NULL); break; } // Иначе считаем что принято имя файла else { if (hdl = fopen(szBuf, "rt")) { // цикл чтения до конца файла while (!feof(hdl)) { // чтение одного символа из файла if ((char)fgetc(hdl) == 0x20) total++; } // сообщение в консоль ошибок sprintf(message, "\n(Server): file:%s, spaces = %d\n", szBuf, total); WriteFile(GetStdHandle(STD_ERROR_HANDLE), message, strlen(message), &cbWritten, NULL); // сообщение в канал sprintf(message, "%d", total); WriteFile(hNamedPipe, message, strlen(message) + 1, &cbWritten, NULL); // закрытие файла fclose(hdl); } else { // сообщение в канал sprintf(message, "(Server)Can't open %s!", szBuf); WriteFile(GetStdHandle(STD_ERROR_HANDLE), message, strlen(message) + 1, &cbWritten, NULL); printf("\n"); WriteFile(hNamedPipe, message, strlen(message) + 1, &cbWritten, NULL); } } } else { printf("ReadFile: Error %ld\n", GetLastError()); break; } } CloseHandle(hNamedPipe); return 0; }