Допустим, первый генерал предлагает время для атаки, но не начнет ее, не будучи уверенным, что второй генерал выдвинулся ему навстречу. Второй принимает приказ и отправляет обратно подтверждение. Но он не будет атаковать, если не будет точно знать, что первый генерал это подтверждение получил (так как в противном случае первый не выступит). Первый генерал получил подтверждение, но не будет атаковать, пока не будет уверен, что второй об этом знает. Следование этой логической цепочке подразумевает бесконечные серии сообщений и, очевидно, ни к чему не приведет. Коммуникация – одна из тех восхитительных вещей, которые работают только на практике; в теории это невозможно.
В большинстве случаев последствия ошибок в коммуникации редко бывают столь плачевными, а потребность в уверенности столь абсолютной. В TCP сбой обычно приводит к повторной передаче данных, а не к смерти, поэтому его обычно достаточно для сеанса, который называют тройным рукопожатием. Посетитель говорит «привет», сервер принимает это «привет» и говорит «привет» в ответ, посетитель принимает, и если сервер получает вот это третье сообщение, то никакого дальнейшего подтверждения уже не требуется. Но даже после того, как это первичное соединение выполнено, остается риск, что последующие пакеты могут быть повреждены, утеряны в процессе передачи или доставлены испорченными. Доставка почтовых отправлений может быть подтверждена уведомлением о вручении; доставка же пакетов онлайн подтверждается тем, что называется пакетами подтверждения, или ACK. Они имеют решающее значение для функционирования сети.
Принцип работы ACK одновременно прост и детально продуман. Помимо сценария тройного рукопожатия, каждый компьютер дает другому нечто вроде серийного номера (и было условлено, что после отправления каждого пакета этот серийный номер увеличивается на единицу, как номера чеков в чековой книжке). К примеру, если ваш компьютер инициирует связь с веб-сервером, он должен отправить этому серверу, скажем, число 100. Посылаемый сервером АСК в свою очередь указывает серийный номер, с которого будут начинаться все отправляемые сервером пакеты (например, 5000), и также сообщает: «Готов к 101». АСК вашего компьютера получает число 101 и передает: «Готов к 5001». (Имейте в виду, что обе эти схемы нумерации независимы друг от друга и число, с которого начинается последовательность, как правило, выбирается случайным образом.)
Такой механизм действия позволяет с точностью определить, в какой момент пакеты сбились с пути. Если сервер ожидает 101, а вместо этого получает 102, он отправит АСК к пакету 102, который все еще гласит: «Готов к 101». Если в ответ он получит следующий пакет 103, то он снова напомнит: «Готов к 101». Три подобных внеочередных АСКа дадут вашему компьютеру сигнал, что 101 не просто задерживается, а безвозвратно потерялся, и он повторно отправит этот пакет. На этот раз сервер (который сохранил пакеты 102 и 103) отправит АСК «Готов к 104», сигнализирующий о том, что последовательность была восстановлена.