Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

лабораторные Тимофеев / 3316_Кирейкова_Лабораторная2

.pdf
Скачиваний:
0
Добавлен:
01.06.2026
Размер:
500.29 Кб
Скачать

Открытие файла. Сначала файл открывается с помощью системного вызова open().

Проецирование в память. Затем с помощью системного

вызова mmap() содержимое файла отображается в виртуальную память процесса. Это создает связь между файлом на диске и областью памяти.

Работа с данными. После проецирования процесс может читать и записывать данные в эту область памяти. Изменения в памяти автоматически синхронизируются с файлом на диске.

Завершение работы. Когда работа с файлом завершена, используется системный вызов munmap() для отключения отображения и функция unlink() для удаления файла.

Код программы

Сервер:

// server.cpp #include <iostream> #include <fcntl.h> #include <sys/mman.h> #include <unistd.h> #include <cstring> #include <cstdlib> #include <sys/stat.h> #include <limits>

using namespace std;

#define FILENAME "ProjectedFile" #define FILESIZE 1024

void Create_and_map_file(int &fd, char **ptr) {

fd = open(FILENAME, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);

if (fd == -1) { perror("Error opening file"); exit(EXIT_FAILURE); }

if (ftruncate(fd, FILESIZE) == -1) { perror("Error setting file size"); close(fd);

exit(EXIT_FAILURE);

}

*ptr = (char *)mmap(nullptr, FILESIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);

if (*ptr == MAP_FAILED) { perror("Error mapping file"); close(fd); exit(EXIT_FAILURE);

}

// Ensure file is zeroed initially memset(*ptr, 0, FILESIZE);

cout << "File created and mapped to memory." << endl;

}

11

void WriteToMemory(char *ptr) { string input;

cout << "Enter text (until the empty line):\n"; string line;

while (true) {

if (!getline(cin, line)) break; if (line.empty()) break;

input += line; input += '\n';

}

//Safely copy to mapped memory (reserve one byte for NUL) size_t to_copy = input.size();

if (to_copy > FILESIZE - 1) to_copy = FILESIZE - 1; memcpy(ptr, input.data(), to_copy);

ptr[to_copy] = '\0';

//Make sure changes are flushed to the underlying file if (msync(ptr, FILESIZE, MS_SYNC) == -1) {

perror("msync failed");

}

cout << "Data has been successfully written to memory." << endl;

}

void UnmapAndDeleteFile(int fd, char *ptr) { if (ptr != nullptr) {

if (munmap(ptr, FILESIZE) == -1) { perror("munmap failed");

}

ptr = nullptr;

}

if (fd != -1) { close(fd); fd = -1;

}

// Remove the file from filesystem if (unlink(FILENAME) == -1) {

perror("unlink failed"); } else {

cout << "File unmapped and deleted." << endl;

}

}

int main() { int choice; int fd = -1;

char *ptr = nullptr;

while (true) {

cout << "\nServer Menu:\n";

cout << "1. Execute projection (create & map file)\n"; cout << "2. Write data\n";

cout << "3. Unmap file and delete\n"; cout << "4. Exit\n";

cout << "Choice: ";

if (!(cin >> choice)) { cin.clear();

cin.ignore(numeric_limits<streamsize>::max(), '\n'); cout << "Invalid input.\n";

continue;

}

cin.ignore(); // consume newline

12

switch (choice) { case 1:

if (ptr != nullptr) {

cout << "File already mapped.\n"; } else {

Create_and_map_file(fd, &ptr);

}

break; case 2:

if (ptr != nullptr) { WriteToMemory(ptr);

} else {

cout << "Memory not mapped. Execute projection first." <<

endl;

}

break; case 3:

if (ptr != nullptr || fd != -1) { UnmapAndDeleteFile(fd, ptr); ptr = nullptr;

fd = -1; } else {

cout << "No mapped file to unmap/delete." << endl;

}

break; case 4:

if (ptr != nullptr || fd != -1) { UnmapAndDeleteFile(fd, ptr);

}

cout << "Exiting server." << endl; return 0;

default:

cout << "Invalid choice. Try again." << endl;

}

}

return 0;

}

Клиент:

// client.cpp #include <iostream> #include <fcntl.h> #include <sys/mman.h> #include <unistd.h> #include <cstring> #include <cstdlib> #include <chrono> #include <thread>

using namespace std;

#define FILENAME "ProjectedFile"

13

#define FILESIZE 1024

void map_and_read_file() {

int fd = open(FILENAME, O_RDONLY); if (fd == -1) {

perror("Error opening file"); return;

}

char *ptr = (char *)mmap(nullptr, FILESIZE, PROT_READ, MAP_SHARED, fd, 0); if (ptr == MAP_FAILED) {

perror("Error mapping file"); close(fd);

return;

}

cout << "File mapped to memory." << endl;

// Простое ожидание данных: опрашиваем содержимое первые 5 секунд const int timeout_seconds = 5;

bool got_data = false;

for (int i = 0; i < timeout_seconds; ++i) {

if (ptr[0] != '\0') { // если первый байт ненулевой — считаем, что данные появились

got_data = true; break;

}

this_thread::sleep_for(chrono::seconds(1));

}

if (!got_data) {

cout << "Timeout: No data available for reading." << endl;

}else {

//Печатаем строку (защищённо, длину ограничиваем FILESIZE)

cout << "Client received:\n";

// ensure null-terminated copy for safe printing

size_t len = strnlen(ptr, FILESIZE);

14

cout.write(ptr, len); cout << endl;

}

if (munmap(ptr, FILESIZE) == -1) { perror("munmap failed");

}

close(fd);

cout << "File unmapped." << endl;

}

int main() { int choice;

while (true) {

cout << "\nClient Menu:\n";

cout << "1. Execute projection and read data\n"; cout << "2. Exit\n";

cout << "Choice: ";

if (!(cin >> choice)) { cin.clear();

cin.ignore(numeric_limits<streamsize>::max(), '\n'); cout << "Invalid input.\n";

continue;

}

switch (choice) { case 1:

map_and_read_file(); break;

case 2:

cout << "Exiting..." << endl; return 0;

default:

cout << "Invalid choice. Try again." << endl;

}

}

15

return 0;

}

Вывод:

В рамках лабораторной работы были разработаны два взаимосвязанных приложения — серверное и клиентское. Сервер отвечал за формирование файла и его настройку для записи данных, в то время как клиент ожидал сигнала о готовности файла и затем осуществлял чтение информации из него.

По завершении работы с файлом была предусмотрена функция его удаления из системы.

Данная реализация наглядно продемонстрировала принципы организации межпроцессного взаимодействия с использованием проецируемых файлов в памяти. Практическая работа позволила углубить понимание механизмов взаимодействия между процессами и освоить особенности управления файлами в рамках клиент-серверной архитектуры.

16