Давайте посмотрим, как TCP посылает срочные данные, даже когда окно получателя закрыто. Мы стартуем программу sock на хосте bsdi и выдержим паузу в течении 10 секунд после того, как соединение будет установлено (опция -P), перед тем как начать читать из сети. Это позволяет удаленному концу заполнить отправляемое окно.
bsdi % sock -i -s -P10 5555
Затем мы стартуем клиента на хосте sun, указав ему установить отправляющий буфер размером 8192 байта (опция -S) и осуществить шесть записей в сеть, каждая размером 1024 байта (опция -n). Также мы указали -U5, что заставляет клиента записать 1 байт данных и войти в режим срочности перед записью в сеть пятого буфера. Также мы установили флаг отладки, чтобы посмотреть в каком порядке будут осуществлены записи:
sun % sock -v -i -n6 -S8192 -U5 bsdi 5555 connected on 140.252.13.33.1305 to 140.252.13.35.5555 SO_SNDBUF = 8192 TCP_MAXSEG = 1024 wrote 1024 bytes wrote 1024 bytes wrote 1024 bytes wrote 1024 bytes wrote 1 byte of urgent data wrote 1024 bytes wrote 1024 bytes
Мы установили размер буфера отправителя в 8192 байта, чтобы позволить отправляющему приложению немедленно записать все свои данные. На рисунке 20.14 показан вывод tcpdump для этого обмена. (Все имеющее отношение к установлению соединения удалено.) В строках 1-5 показано, как отправитель заполняет окно приемника четырьмя сегментами по 1024 байта. Затем отправитель останавливается, потому что окно приемника заполнено. (Подтверждение в строке 4 подтверждает данные, однако не перемещает правую границу окна.)
После того как приложение осуществило четыре обычные записи данных, приложение пишет 1 байт данных и входит в режим срочности. В строке 6 показан результат этой записи. Указатель срочности установлен в 4098. Указатель срочности отправляется с флагом URG, даже если отправитель не может послать какие-либо данные.
Пять из этих подтверждений (ACK) отправляются примерно в течение 13 миллисекунд (строки 6-10). Первое отправляется, когда приложение пишет 1 байт и входит в режим срочности. Следующие два отправляются, когда приложение осуществляет две последние записи, каждая по 1024 байта. (Даже если TCP не может отправить эти 2048 байт данных, каждый раз, когда приложение осуществляет запись, вызывается функция вывода TCP, и когда она видит, что осуществлен вход в режим срочности, то посылает еще одно уведомление о срочности.) Четвертый из этих ACK появляется, когда приложение со своей стороны закрывает соединение. (В этом случае снова вызывается функция вывода TCP.) Отправляющее приложение прекратило свою работу через несколько миллисекунд после старта - перед тем как принимающее приложение осуществило свою первую запись. TCP поставило в очередь все данные и отправляет их по возможности. (Именно поэтому мы указали размер буфера равный 8192 байта - таким образом, все данные могут поместиться в буфер.) Пятый из этих ACK сгенерирован на получение ACK в строке 4. Отправляющий TCP возможно уже поставил в очередь четвертый сегмент для вывода (строка 5), перед тем как прибыл этот ACK. Приход этого ACK от удаленной стороны также приводит к вызову подпрограммы вывода TCP.