Лаб. работа “Типы исключительных ситуаций и процесс их обработки”
Цель работы
Изучить механизм обработки исключительных ситуаций в C++ (try-catch) путём разработки консольного приложения, имитирующего отправку данных по сети. Освоить перехват и обработку стандартных исключений при парсинге входных данных и при сшибках на этапе «отправки».
Теоретические сведения
Понятие исключительной ситуации
Исключение — это ситуация, возникающая во время выполнения программы, которая нарушает нормальный ход её работы. Механизм обработки исключений позволяет отделить код обнаружения ошибки от кода её обработки.
Иерархия стандартных исключений C++
Синтаксис try-catch
try {
// код, который может вызвать исключение
if (port < 0 || port > 65535)
throw std::out_of_range("Порт вне диапазона 0-65535");
} catch (const std::out_of_range& e) {
cerr << "Ошибка диапазона: " << e.what() << endl;
} catch (const std::exception& e) {
cerr << "Ошибка: " << e.what() << endl;
} catch (...) {
cerr << "Неизвестная ошибка" << endl;
}Пользовательские исключения
class NetworkException : public std::runtime_error {
private:
int errorCode;
public:
NetworkException(const string& msg, int code)
: runtime_error(msg), errorCode(code) {}
int getErrorCode() const { return errorCode; }
};
class ConnectionRefusedException : public NetworkException {
public:
ConnectionRefusedException(const string& ip, int port)
: NetworkException("Соединение отклонено: " + ip + ":" + to_string(port), 10061) {}
};
class TimeoutException : public NetworkException {
private:
int timeoutMs;
public:
TimeoutException(int ms)
: NetworkException("Таймаут соединения: " + to_string(ms) + "мс", 10060), timeoutMs(ms) {}
int getTimeout() const { return timeoutMs; }
};Генерация исключений при парсинге
#include <stdexcept>
int parsePort(const string& input) {
if (input.empty())
throw std::invalid_argument("Пустая строка");
for (char c : input) {
if (!isdigit(c))
throw std::invalid_argument("Порт должен содержать только цифры: " + input);
}
int port = stoi(input);
if (port < 1 || port > 65535)
throw std::out_of_range("Порт вне диапазона 1-65535: " + to_string(port));
return port;
}Задание для выполнения
Разработать консольное приложение, имитирующее отправку данных по сети с обработкой стандартных и пользовательских исключений.
Требования к программе
Создать пользовательские классы исключений (наследники
std::runtime_error):NetworkException— базовое сетевое исключение, содержит код ошибки (int)ConnectionRefusedException— соединение отклонено (IP + порт)TimeoutException— таймаут соединения (значение таймаута в мс)DataFormatException— неверный формат данных (описание ошибки)AuthenticationException— ошибка аутентификации (имя пользователя)
Реализовать функции с генерацией исключений:
int parsePort(const string& input)— парсинг порта: проверка на цифры, диапазон 1–65535string parseIpAddress(const string& input)— проверка формата IP (4 октета, 0–255)void validateCredentials(const string& login, const string& password)— проверка: длина логина ≥ 3, длина пароля ≥ 6, пароль содержит цифруvoid simulateSend(const string& ip, int port, const string& data, int timeout)— имитация отправки: случайным образом генерирует исключенияConnectionRefusedException(вероятность 20%),TimeoutException(15%),DataFormatException(10%). Если ошибок нет — выводит сообщение об успешной отправке.
Реализовать текстовое меню:
1. Отправить данные (полный цикл: парсинг → валидация → отправка) 2. Проверить формат IP-адреса 3. Проверить учётные данные 4. Демо всех типов исключений 0. ВыходВ пункте 1 пользователь вводит IP, порт, логин, пароль, данные, таймаут. Программа последовательно вызывает функции парсинга и отправки. Каждое исключение обрабатывается с выводом информативного сообщения, при этом выполнение не прерывается — пользователь возвращается в меню.
Пример ожидаемого вывода
=== Отправка данных ===
IP-адрес: 192.168.1.300
Ошибка: IP-адрес некорректен: октет 300 вне диапазона 0-255
IP-адрес: 192.168.1.1
Порт: abc
Ошибка: Порт должен содержать только цифры: abc
Порт: 8080
Логин: ab
Ошибка: Длина логина должна быть не менее 3 символов
Логин: admin
Пароль: qwerty
Ошибка: Пароль должен содержать хотя бы одну цифру
Пароль: qwerty1
Данные: Hello Server
Таймаут (мс): 5000
[ОК] Данные отправлены на 192.168.1.1:8080 (протокол TCP, 11 байт, 5мс)
=== Демо исключений ===
[ConnectionRefused] Соединение отклонено: 10.0.0.1:80 (код: 10061)
[Timeout] Таймаут соединения: 30000мс (код: 10060)
[DataFormat] Неверный формат пакета: отсутствует заголовок
Индивидуальные задания
Каждый вариант предполагает разработку консольного приложения на C++ с собственными классами исключений (наследники std::runtime_error), функциями валидации и имитации сетевых операций, а также текстовым меню с полной обработкой исключений через try-catch.
Вариант 1. Валидация DNS-записей
Исключения: DNSException (код ошибки), InvalidDomainException (домен), InvalidIPException (IP), RecordNotFoundException (домен). Функции: parseDomain(name) — проверка формата домена, parseIP(ip) — проверка октетов 0–255, lookupRecord(domain) — имитация поиска (20% — RecordNotFoundException), addRecord(domain, ip) — добавление записи.
| Пункт меню | Функция | Возможные исключения |
|---|---|---|
| 1. Найти запись | lookupRecord(domain) |
RecordNotFoundException, InvalidDomainException |
| 2. Добавить запись | addRecord(domain, ip) |
InvalidDomainException, InvalidIPException |
| 3. Проверить домен | parseDomain(name) |
InvalidDomainException |
| 4. Проверить IP | parseIP(ip) |
InvalidIPException |
| 5. Демо исключений | — | все типы |
Вариант 2. Обработка FTP-команд
Исключения: FTPException (базовое, код ошибки), FileNotFoundException, PermissionDeniedException, DiskFullException.
| Пункт меню | Функция | Возможные исключения |
|---|---|---|
| 1. Загрузить файл | simulateUpload(filename, size) |
FileNotFoundException, PermissionDeniedException, DiskFullException |
| 2. Скачать файл | simulateDownload(filename) |
FileNotFoundException, PermissionDeniedException |
| 3. Удалить файл | validateFilename(name) |
FileNotFoundException, PermissionDeniedException |
| 4. Список файлов | parsePath(path) |
invalid_argument |
| 5. Демо исключений | — | все типы |
Вариант 3. Парсинг HTTP-заголовков
Исключения: HTTPException (базовое, код ошибки), InvalidURLException, InvalidHeaderException, TimeoutException.
| Пункт меню | Функция | Возможные исключения |
|---|---|---|
| 1. Отправить запрос | simulateRequest(url) |
InvalidURLException, TimeoutException |
| 2. Парсинг URL | parseURL(url) |
InvalidURLException |
| 3. Проверить заголовок | parseHeader(header) |
InvalidHeaderException |
| 4. Проверить код ответа | validateStatusCode(code) |
out_of_range, invalid_argument |
| 5. Демо исключений | — | все типы |
Вариант 4. Проверка почтовых адресов
Исключения: MailException (базовое, код ошибки), InvalidEmailException, AttachmentTooLargeException, RecipientNotFoundException.
| Пункт меню | Функция | Возможные исключения |
|---|---|---|
| 1. Отправить письмо | simulateSendEmail(from, to, subject) |
InvalidEmailException, RecipientNotFoundException, AttachmentTooLargeException |
| 2. Проверить email | validateEmail(email) |
InvalidEmailException |
| 3. Проверить вложение | validateAttachment(filename, size) |
AttachmentTooLargeException |
| 4. Парсинг получателей | parseRecipientList(list) |
InvalidEmailException |
| 5. Демо исключений | — | все типы |
Вариант 5. Обработка конфигурации сервера
Исключения: ConfigException (базовое, код ошибки), MissingKeyException, InvalidValueException, DuplicateKeyException.
| Пункт меню | Функция | Возможные исключения |
|---|---|---|
| 1. Загрузить конфиг | loadConfig(filename) |
MissingKeyException, InvalidValueException, DuplicateKeyException |
| 2. Проверить порт | validatePort(port) |
InvalidValueException |
| 3. Проверить IP | validateIP(ip) |
InvalidValueException |
| 4. Добавить параметр | parseConfigLine(line) |
InvalidValueException, DuplicateKeyException |
| 5. Демо исключений | — | все типы |
Вариант 6. Валидация формата данных
Исключения: DataException (базовое, код ошибки), InvalidFormatException, ChecksumException, CorruptedException.
| Пункт меню | Функция | Возможные исключения |
|---|---|---|
| 1. Парсинг пакета | parsePacket(data) |
InvalidFormatException, CorruptedException |
| 2. Проверка контрольной суммы | validateChecksum(data, expected) |
ChecksumException |
| 3. Сериализация | serializePacket(packet) |
InvalidFormatException |
| 4. Валидация формата | parseDataFormat(data) |
InvalidFormatException |
| 5. Демо исключений | — | все типы |
Вариант 7. Аутентификация пользователей
Исключения: AuthException (базовое, код ошибки), InvalidCredentialsException, AccountLockedException, SessionExpiredException.
| Пункт меню | Функция | Возможные исключения |
|---|---|---|
| 1. Войти | authenticate(login, password) |
InvalidCredentialsException, AccountLockedException |
| 2. Проверить логин | validateLogin(login) |
InvalidCredentialsException |
| 3. Проверить пароль | validatePassword(password) |
InvalidCredentialsException |
| 4. Проверить сессию | checkSession(userId) |
SessionExpiredException |
| 5. Демо исключений | — | все типы |
Вариант 8. Обработка SQL-запросов
Исключения: QueryException (базовое, код ошибки), SyntaxErrorException, TableNotFoundException, ConstraintViolationException.
| Пункт меню | Функция | Возможные исключения |
|---|---|---|
| 1. Выполнить запрос | simulateExecute(query) |
SyntaxErrorException, TableNotFoundException, ConstraintViolationException |
| 2. Парсинг запроса | parseQuery(query) |
SyntaxErrorException |
| 3. Проверить таблицу | validateTableName(name) |
TableNotFoundException |
| 4. Проверить столбец | validateColumn(name) |
ConstraintViolationException |
| 5. Демо исключений | — | все типы |
Вариант 9. Работа с SSH-подключениями
Исключения: SSHException (базовое, код ошибки), HostKeyException, AuthenticationFailedException, ConnectionTimeoutException.
| Пункт меню | Функция | Возможные исключения |
|---|---|---|
| 1. Подключиться | simulateSSHConnect(host, user) |
HostKeyException, AuthenticationFailedException, ConnectionTimeoutException |
| 2. Проверить хост | parseHost(host) |
invalid_argument |
| 3. Проверить ключ | validateKey(key) |
HostKeyException |
| 4. Проверить порт | validatePort(port) |
out_of_range |
| 5. Демо исключений | — | все типы |
Вариант 10. Валидация REST API-запросов
Исключения: APIException (базовое, код ошибки), InvalidEndpointException, MethodNotAllowedException, RateLimitException.
| Пункт меню | Функция | Возможные исключения |
|---|---|---|
| 1. Выполнить запрос | simulateAPIRequest(method, endpoint, data) |
InvalidEndpointException, MethodNotAllowedException, RateLimitException |
| 2. Проверить endpoint | parseEndpoint(endpoint) |
InvalidEndpointException |
| 3. Проверить метод | validateMethod(method) |
MethodNotAllowedException |
| 4. Проверить payload | validatePayload(payload) |
invalid_argument |
| 5. Демо исключений | — | все типы |
Вариант 11. Обработка WebSocket-сообщений
Исключения: WSException (базовое, код ошибки), HandshakeFailedException, FrameException, ConnectionClosedException.
| Пункт меню | Функция | Возможные исключения |
|---|---|---|
| 1. Отправить сообщение | simulateSendMessage(data) |
ConnectionClosedException, FrameException |
| 2. Парсинг фрейма | parseFrame(data) |
FrameException |
| 3. Проверить handshake | validateHandshake(headers) |
HandshakeFailedException |
| 4. Проверить размер | validatePayloadSize(size) |
out_of_range |
| 5. Демо исключений | — | все типы |
Вариант 12. Сетевой сканер (имитация)
Исключения: ScanException (базовое, код ошибки), InvalidRangeException, TimeoutException, PermissionDeniedException.
| Пункт меню | Функция | Возможные исключения |
|---|---|---|
| 1. Сканировать хост | simulateScan(ip, port) |
TimeoutException, PermissionDeniedException |
| 2. Проверить диапазон IP | parseIPRange(range) |
InvalidRangeException |
| 3. Проверить диапазон портов | validatePortRange(start, end) |
InvalidRangeException, out_of_range |
| 4. Парсинг цели | parseTarget(target) |
InvalidRangeException |
| 5. Демо исключений | — | все типы |
Вариант 13. Работа с сертификатами
Исключения: CertException (базовое, код ошибки), ExpiredException, InvalidChainException, DomainMismatchException.
| Пункт меню | Функция | Возможные исключения |
|---|---|---|
| 1. Проверить сертификат | parseCertificate(data) |
CertException |
| 2. Проверить срок | validateExpiry(date) |
ExpiredException |
| 3. Проверить домен | validateDomain(certDomain, targetDomain) |
DomainMismatchException |
| 4. Проверить цепочку | checkChain(certs) |
InvalidChainException |
| 5. Демо исключений | — | все типы |
Вариант 14. Обработка ICMP-пакетов
Исключения: PingException (базовое, код ошибки), HostUnreachableException, TTLExceededException, PacketTooBigException.
| Пункт меню | Функция | Возможные исключения |
|---|---|---|
| 1. Пинг хоста | simulatePing(host, count) |
HostUnreachableException, TTLExceededException, PacketTooBigException |
| 2. Проверить IP | parseIPAddress(ip) |
invalid_argument |
| 3. Проверить TTL | validateTTL(ttl) |
TTLExceededException |
| 4. Проверить размер пакета | validatePacketSize(size) |
PacketTooBigException |
| 5. Демо исключений | — | все типы |
Вариант 15. Маршрутизация пакетов
Исключения: RouteException (базовое, код ошибки), NoRouteException, InvalidMaskException, GatewayUnavailableException.
| Пункт меню | Функция | Возможные исключения |
|---|---|---|
| 1. Маршрутизация | simulateRoute(destIP) |
NoRouteException, GatewayUnavailableException |
| 2. Парсинг маршрута | parseRouteEntry(entry) |
InvalidMaskException, invalid_argument |
| 3. Проверить маску | validateMask(mask) |
InvalidMaskException |
| 4. Проверить шлюз | validateGateway(ip) |
GatewayUnavailableException |
| 5. Демо исключений | — | все типы |
Вариант 16. Обработка JSON-конфигурации
Исключения: JSONException (базовое, код ошибки), ParseErrorException, MissingFieldException, TypeMismatchException.
| Пункт меню | Функция | Возможные исключения |
|---|---|---|
| 1. Загрузить конфиг | loadServerConfig(json) |
ParseErrorException, MissingFieldException, TypeMismatchException |
| 2. Получить поле | getField(json, key) |
MissingFieldException, ParseErrorException |
| 3. Проверить тип | validateType(value, expectedType) |
TypeMismatchException |
| 4. Парсинг JSON | parseJSON(json) |
ParseErrorException |
| 5. Демо исключений | — | все типы |
Вариант 17. Работа с прокси-сервером
Исключения: ProxyException (базовое, код ошибки), ProxyAuthException, BlockedHostException, ConnectionRefusedException.
| Пункт меню | Функция | Возможные исключения |
|---|---|---|
| 1. Запрос через прокси | simulateProxyRequest(proxy, target) |
ProxyAuthException, BlockedHostException, ConnectionRefusedException |
| 2. Проверить адрес прокси | parseProxyAddress(address) |
invalid_argument |
| 3. Проверить URL | validateTargetURL(url) |
BlockedHostException |
| 4. Проверить чёрный список | checkBlocklist(domain) |
BlockedHostException |
| 5. Демо исключений | — | все типы |
Вариант 18. Обработка сетевых событий
Исключения: EventException (базовое, код ошибки), InvalidEventException, QueueFullException, HandlerNotFoundException.
| Пункт меню | Функция | Возможные исключения |
|---|---|---|
| 1. Опубликовать событие | simulatePublishEvent(type, data) |
InvalidEventException, QueueFullException, HandlerNotFoundException |
| 2. Парсинг события | parseEvent(data) |
InvalidEventException |
| 3. Проверить тип | validateEventType(type) |
InvalidEventException |
| 4. Проверить очередь | validateQueueSize(size) |
QueueFullException |
| 5. Демо исключений | — | все типы |
Вариант 19. Работа с сетевым кэшем
Исключения: CacheException (базовое, код ошибки), KeyNotFoundException, CacheFullException, SerializationException.
| Пункт меню | Функция | Возможные исключения |
|---|---|---|
| 1. Получить значение | simulateGet(key) |
KeyNotFoundException, SerializationException |
| 2. Сохранить значение | simulatePut(key, value) |
CacheFullException, SerializationException |
| 3. Проверить ключ | validateKey(key) |
invalid_argument |
| 4. Проверить размер кэша | validateCacheSize(size) |
CacheFullException |
| 5. Демо исключений | — | все типы |
Вариант 20. Обработка XML-конфигурации
Исключения: XMLException (код ошибки), TagNotFoundException (тег), AttributeFormatException (атрибут), NestingException (уровень вложенности). Функции: parseTag(xml, tagName) — поиск открывающего и закрывающего тега, validateAttribute(value, type) — проверка типа значения (int/string/bool), parseConfig(xml) — парсинг конфигурации (30% — TagNotFoundException), validateStructure(xml) — проверка баланса тегов. Меню: 1. Загрузить конфигурацию, 2. Получить значение тега, 3. Проверить атрибут, 4. Проверить структуру, 5. Демо исключений, 0. Выход.
Порядок выполнения
- Создать проект C++ в Qt Creator (CMake).
- Определить иерархию пользовательских исключений.
- Реализовать функции парсинга и валидации с генерацией исключений.
- Реализовать функцию имитации отправки
simulateSend(). - Реализовать меню с полной обработкой исключений через
try-catchблоки. - Протестировать: ввести корректные и некорректные данные, убедиться в обработке всех типов исключений.
- Скомпилировать, запустить, сохранить скриншоты.
Контрольные вопросы
- Что такое исключение и зачем нужен механизм обработки исключений?
- Какие стандартные классы исключений вы использовали? В чём разница между
logic_errorиruntime_error? - Что делает оператор
throw? Можно ли бросать исключение любого типа? - Что произойдёт, если исключение не перехватить ни одним блоком
catch? - Зачем нужен блок
catch(...)и когда его следует использовать? - Какой порядок выполнения блоков
catchпри наследовании исключений? Почему важен порядок? - Что такое
e.what()и какую информацию он возвращает? - Чем создание пользовательского класса исключения лучше генерации
std::runtime_error("текст")? - В чём разница между обработкой ошибок через исключения и через коды возврата?
Содержание отчёта
- Тема, цель и задание лабораторной работы.
- Диаграмма иерархии пользовательских исключений.
- Текст программы с комментариями.
- Скриншоты: успешная отправка, обработка каждого типа исключения.
- Ответы на контрольные вопросы.
