что такое nak и ack
Что такое nak и ack
Протокол XMODEM был разработан довольно давно, в 1977 году (автор Ward Christensen), для предоставления возможности обмениваться данными двум компьютерам через модем (обмен типа точка-точка). В протоколе применен полудуплексный принцип обмена данными, блоками по 128 байт, с кодами квитирования ACK/NACK и проверкой данных с помощью CRC. Благодаря простоте и открытой документации протокол XMODEM нашел широкое применение во многих приложениях. Фактически большинство коммуникационных пакетов, доступных для PC, имеют встроенную поддержку передачи данных через XMODEM.
Из-за своей простоты XMODEM удобно использовать на встраиваемых системах [3], где всегда имеется дефицит по вычислительным ресурсам и памяти. Хорошо получаются загрузчики кода [4], позволяющие перепрошивать программу системы по последовательному каналу связи с помощью готовых утилит терминала. Полудуплексный принцип работы позволяет использовать простейшие физические каналы связи. Например, передатчик и приемник может соединять единственный сигнальный провод (либо это может быть радиоканал на общей частоте для передатчика и приемника), который переключается с приема на передачу, потому что протокол XMODEM не подразумевает одновременной передачи на обоих концах канала связи.
[Немного теории]
XMODEM является полудуплексным (half-duplex) протоколом обмена данными. Протокол не подходит для канала связи, где элементарная посылка состоит менее чем из 8 бит. Приемник после приема пакета будет либо подтвердит (acknowledge, ACK), либо не подтвердит его (not acknowledge, NAK). Улучшенный по сравнению с оригинальной реализацией XMODEM (которая использовала 1 байт CRC) подсчет контрольной суммы CRC использует более надежную 16-разрядную CRC для проверки целостности принятого блока данных. Протокол XMODEM можно считать протоколом, управляемым со стороны приемника, потому что передатчик не обязан автоматически запускать повторные передачи без участия приемника. Однако все-таки во многих реализациях протокола передатчик самостоятельно запускает передачу пакетов при отсутствии активности приемника.
Кратко обмен данными можно описать следующим образом. Приемник начинает обмен предварительными приглашающими посылками символа NAK или «C» в сторону передатчика, чтобы показать свою готовность к приему данных. После этого передатчик посылает 132-байтный (если посылалось приглашение NAK) или 133-байтный пакет (если посылалось приглашение в виде символа ‘C’). Затем приемник проверяет пакет и отвечает кодом ACK или NAK, и в зависимости от этого передатчик либо посылает следующий пакет (если от приемника было подтверждение ACK), либо повторно посылает последний пакет (если от приемника пришел код NAK). Этот процесс продолжается до тех пор, пока приемник не получит код EOT, после чего приемник должен подтвердить завершение приема файла посылкой кода ACK в сторону передатчика. После начальной установки связи (initial handshake) приемник управляет потоком данных с помощью отправки передатчику кодов ACK и NAK.
В таблице представлены управляющие коды (символы) протокола XMODEM.
Таблица 1.1. Специальные символы протокола XMODEM.
Символ | Значение | Описание |
SOH | 0x01 | Start of Header, начало заголовка. |
EOT | 0x04 | End of Transmission, конец передачи. |
ACK | 0x06 | Acknowledge, положительное подтверждение. |
NAK | 0x15 | Not Acknowledge, отрицательное подтверждение. |
ETB | 0x17 | End of Transmission Block, конец передачи блока. |
CAN | 0x18 | Cancel, отмена обмена. Этот символ, посылаемый передатчиком, принуждает приемник отправлять символы ‘C’ или NAK. |
C | 0x43 | Код ASCII ‘C’. |
ctrl/z | 0x1A | Маркер конца файла. Этим кодом заполняется пустое пространство последнего передаваемого блока, дополняя его по размеру до 128 байт. |
Передаваемые полезные данные (например файл) могут быть любой длины, однако они передаются блоками жесткого размера, по 128 байт, и протокол не поддерживает передачу точного размера пересылаемого блока данных (файла). Если содержимое данных не укладываются точно в 128-байтную границу по размеру, то необязательно, но желательно, чтобы остальная часть данных была заполнена так называемыми символами ctl/z (код ASCII 0x1A) конца файла (EOF, End of File). Последний передаваемый блок не отличается от всех остальных, таким образом нет «коротких блоков». Некоторые утилиты или программы пользователя не обрабатывают поддержку окончания файла без наличия символов ctrl/z.
Формат пакета XMODEM с поддержкой CRC8 (оригинальный XMODEM):
Байт 1 | Байт 2 | Байт 3 | Байты 4..131 | Байт 132 |
Start of Header (SOH, начало заголовка) | Номер пакета | Номер пакета (дополнение) | Данные пакета | 8-bit CRC |
Формат пакета XMODEM с поддержкой CRC16 (XmodemCRC):
Байт 1 | Байт 2 | Байт 3 | Байты 4..131 | Байты 132, 133 |
Start of Header (SOH, начало заголовка) | Номер пакета | Номер пакета (дополнение) | Данные пакета | 16-bit CRC |
Передатчик определит тип используемого протокола (с CRC8 или с CRC16) по байту приглашения, который отправляет приемник. Если приемник передает байт приглашения NAK, то используется пакет с CRC8, если же приемник передает байт приглашения в виде символа ‘C’, то это означает использование пакета с CRC16.
Синхронизация между приемником и передатчиком. Как уже упоминалось, приемник начинает сессию обмена с периодических (с интервалом примерно 3 сек) посылок передатчику символа ASCII “C” (код 0x43), чем показывая передатчику, что ожидается отправка блока с поддержкой проверки алгоритмом CRC. После отправки символа “C” ждет либо истечения таймаута 3 секунды, либо появления в приемном буфере символа от передатчика. При появлении символа он записывается во внутренний буфер, и таймаут сбрасывается. Если символ от передатчика не поступил и таймаут истек, то приемник снова посылает другой символ “C” передатчику, и снова ждет 3 секунды. Этот процесс продолжается, пока приемник не примет полный пакет из 133 байт.
Как только приемник вошел в прием блока, для каждого принимаемого символа и контрольной суммы используется таймаут в 1 секунду. Если приемник хотел бы послать NAK по какой-то любой причине (неправильный заголовок, ошибка фрейма, истек таймаут в процессе приема данных), он должен ожидать чистой линии на входе (когда передатчик ничего не передает в течение 1 секунды). Подробнее см. ниже «Советы по программированию».
Обычно (когда передатчик, приемник и канал связи исправны) в протоколе XMODEM коды NAK используются для следующих ситуаций:
1. Ошибка фрейма (Frame error) при приеме любого байта.
2. Переполнение буфера приема (Overrun error) для любого принятого байта.
3. Повторная отправка пакета.
4. Ошибка CRC.
5. Таймаут приемника (не было приема пакета в течение 1 секунды).
Все ошибки в канале связи исправляются 10-ю повторными попытками передачи блока. Если у принятого блока не те атрибуты, которые ожидались, то приемник посылает NAK, и увеличивает свой счетчик повторных попыток. После того, как было 10 неудачных повторов, сеанс связи считается завершенным из-за потери синхронизации.
Если был принят допустимый номер блока, то это может означать следующее:
1. Этот блок ожидался, в этом случае все в порядке.
2. Это копия ранее принятого блока (номер блока совпал с предыдущим). В этом случае можно считать, что тоже все в порядке, просто показывает, что передатчик по каким-то причинам передатчик принял поврежденный символ ACK, и передал блок заново.
3. Какой-то другой номер блока. Эта ситуация показывает фатальную потерю синхронизации, как например если бы у передатчика были сильные помехи на входе, которые были ошибочно восприняты как символы ACK. В этом случае следует прервать передачу отправкой CAN, после чего запустить сеанс связи повторно.
Алгоритм работы передатчика. Когда передатчик ждет начала передачи, у него есть только один очень большой таймаут, скажем в 1 минуту. Однако во многих текущих реализациях протокола после начала сеанса связи у передатчика есть 10-секундный таймаут, после которого передатчик предпримет повторную передачу блока. Однако разработчик протокола Ward Christensen не рекомендует так делать, оставляя протокол на управление только со стороны приемника. Это сохранит совместимость с уже существующими программами.
Когда у передатчика больше нет данных для отправки, он посылает EOT, ждет ACK, и снова посылает EOT, если ACK не получен. Опять-таки, протокол и в этом случае можно оставить на управление со стороны приемника, и сделать для передатчика единственный таймаут в 1 минуту, после которого передатчик может разорвать сеанс связи.
[Пример сеанса связи]
В таблице для иллюстрации принципа работы протокола XMODEM показан примерный сеанс связи с восстановлением из ситуации с ошибками. Вся передача файла в этом примере состоит из 5 блоков, некоторые из которых передаются повторно.
Передатчик | Приемник | ||||
Пакет принят успешно | |||||
Повреждение на линии во время передачи | |||||
Пакет принят успешно | |||||
Пакет принят успешно | |||||
(ACK не принят из-за помех) | (Ошибка фрейма на любом байте) | ||||
(Ошибка переполнения приема на любом байте) | |||||
Пакет принят успешно | |||||
Пакет принят успешно | |||||
Завершение сеанса приема | |||||
Завершение сеанса передачи |