Полезная нагрузка данных в TCP ack

#tcp

#tcp

Вопрос:

Я просматриваю некоторые сетевые трассировки и заметил на своей собственной машине, что при подключении через HTTP пакеты выглядят примерно так:

 client --> server: GET
server --> client: tcp ack
server --> client: HTTP response
client --> server: tcp ack
 

Тем не менее, я просмотрел некоторые следы CIFS (SMB), которые я сохранил несколько лет назад. Я вижу такие вещи, как:

 client --> server: Create Request 
server --> client: Create response (This packet also acks the request)
 

На высоком уровне мне интересно, в чем разница — что вызывает разное поведение? Что контролирует, помещается ли ответ приложения в запрос ack или другой пакет: приложение или ОС?

Ответ №1:

Такое поведение зависит как от операционной системы, так и от приложения. В Linux ядро не отправляет ACK напрямую, а вместо этого ожидает фиксированное количество миллисекунд (около 200), надеясь, что у него есть какие-то данные для отправки обратно, и он может позволить ACK выполнить контурную передачу данных.

Если таймер сработает, то подтверждение будет отправлено немедленно.

Пример 1.

 Client sends the GET request.

Server tries to create a http response, but before it does that 200ms are gone
and it must send the ACK before the http response.
 

Пример 2.

 Client sends the GET request.

Server creates a http response within the timer limit, and the ACK can piggyback
the data.
 

Это означает, что если ваше приложение стало медленнее генерировать этот ответ, подтверждение будет отправлено без привязки к данным. А также, в зависимости от операционной системы, таймер задержки может быть выше / ниже и еще раз изменять способ отправки подтверждений.

Комментарии:

1. можете ли вы указать таймер задержки в каких-либо настройках инициализации TCP?

2. Вы можете отключить ее с помощью опции TCP_QUICKACK с помощью setsockopt в разделе IPPROTO_TCP (кстати, непереносимый). Но изменение значения может быть невозможно, поскольку я считаю, что оно жестко запрограммировано, если для него нет недавно добавленного sysctl (или чего-то подобного).

3. После того, как я установил параметр TCP socket для отключения TCP Quick ACK, я все еще не получил ответа на комбинированный пакет: opt = 0; setsockopt(sockfd, IPPROTO_TCP, TCP_QUICKACK, (char *) amp;opt, sizeof(opt));

4. Вы также можете сделать это с помощью IP-маршрутов serverfault.com/a/952638/87556