#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