Я являюсь сетевым трафиком и хочу разделить каждый сеанс TCP на серию запросов и ответов (все протоколы, с которыми я работаю, работают так же, как HTTP или SSL).
У меня было простое предположение (игнорирование неупорядоченных и повторно отправленных пакетов) - учитывая кусок данных, которые должны быть отправлены, они будут отправлены с использованием максимально возможных пакетов, а последний пакет будет либо меньше максимального размера, либо будет сопровождаться пакетом с другой стороны (игнорируя пустые пакеты ACK). Так что в сеансе HTTP я ожидаю увидеть что-то вроде (опять же, игнорируя acks) -
Пакет 1 - Запрос "Получить ..."
Пакет 2 - Ответ, размер 1434
Пакет 3 - Ответ, размер 1434
Пакет 4 - Ответ, размер 1434
Пакет 5 - Ответ, размер 500
Это то, что я получаю на большинстве сессий, однако я видел, по крайней мере, один случай, который выглядел как
Пакет 1 - Запрос "Получить ..."
Пакет 2 - Ответ, размер 1434
Пакет 3 - Ответ, размер 1080
Пакет 4 - Ответ, размер 1434
Пакет 5 - Ответ, размер 500
Здесь нет повторных передач, неупорядоченных пакетов или исключительных задержек на сервере.
Я хочу знать - что может вызвать это и когда это произойдет? Насколько неверно мое предположение?
ОБНОВИТЬ
Я положил пример файла pcap здесь
ОБНОВЛЕНИЕ 2
Включая tshark
дамп с соответствующими полями ...
$ tshark -r http_1082.pcap -T fields -e frame.number -e frame.len \
-e ip.src -e ip.dst -e tcp.flags.push -e http.request.method \
-e http.request.uri -e http.response.code | head -n 47
1 66 192.168.1.103 206.33.49.126 0
2 62 206.33.49.126 192.168.1.103 0
3 64 192.168.1.103 206.33.49.126 0
4 411 192.168.1.103 206.33.49.126 1 GET /money/.element/script/3.0/video/xmp/xmp_playlistapi.js
5 54 206.33.49.126 192.168.1.103 0
6 1434 206.33.49.126 192.168.1.103 0
7 1434 206.33.49.126 192.168.1.103 0
8 64 192.168.1.103 206.33.49.126 0
9 1434 206.33.49.126 192.168.1.103 0
10 1434 206.33.49.126 192.168.1.103 0
11 1434 206.33.49.126 192.168.1.103 0
12 64 192.168.1.103 206.33.49.126 0
13 1434 206.33.49.126 192.168.1.103 0
14 1434 206.33.49.126 192.168.1.103 0
15 1434 206.33.49.126 192.168.1.103 0
16 1434 206.33.49.126 192.168.1.103 0
17 64 192.168.1.103 206.33.49.126 0
18 1434 206.33.49.126 192.168.1.103 0
19 1434 206.33.49.126 192.168.1.103 0
20 1434 206.33.49.126 192.168.1.103 0
21 1434 206.33.49.126 192.168.1.103 0
22 1434 206.33.49.126 192.168.1.103 0
23 64 192.168.1.103 206.33.49.126 0
24 1434 206.33.49.126 192.168.1.103 0
25 1434 206.33.49.126 192.168.1.103 0
26 1434 206.33.49.126 192.168.1.103 0
27 1434 206.33.49.126 192.168.1.103 0
28 1434 206.33.49.126 192.168.1.103 0
29 1434 206.33.49.126 192.168.1.103 0
30 64 192.168.1.103 206.33.49.126 0
31 1434 206.33.49.126 192.168.1.103 0
32 1434 206.33.49.126 192.168.1.103 0
33 1434 206.33.49.126 192.168.1.103 0
34 1082 206.33.49.126 192.168.1.103 1 <------ Packet in question
35 1434 206.33.49.126 192.168.1.103 0
36 1434 206.33.49.126 192.168.1.103 0
37 1434 206.33.49.126 192.168.1.103 0
38 64 192.168.1.103 206.33.49.126 0
39 1434 206.33.49.126 192.168.1.103 0
40 1434 206.33.49.126 192.168.1.103 0
41 1434 206.33.49.126 192.168.1.103 0
42 1434 206.33.49.126 192.168.1.103 0
43 1434 206.33.49.126 192.168.1.103 0
44 1434 206.33.49.126 192.168.1.103 0
45 1434 206.33.49.126 192.168.1.103 0
46 626 206.33.49.126 192.168.1.103 1 200
47 64 192.168.1.103 206.33.49.126 0
Ответы:
Уровень TCP использует алгоритм Nagle для буферизации трафика (он отправляет меньше больших пакетов вместо более маленьких пакетов ... что делает его более эффективным); у приложения есть способ сказать «отправить сейчас». Вы видите это в заголовке TCP с флагом, называемым битом PSH (push). Пока бит задается стеком, отправка выполняется по запросу приложения.
Так что это намеренное и нормальное поведение.
источник
Размер пакета зависит от того, как приложение и / или ОС буферизируют и отправляют сетевые данные. Если приложение и / или ОС решают отправить данные после того, как 1080 байт находятся в буфере, то пакет будет 1080 байтов (плюс заголовки). Для этого может быть много причин. В вашем случае вам придется искать исходный код веб-сервера и / или сетевой стек ОС.
источник
Размер пакета определяется ОС (в целом) и связан с буферами, объемом данных, предоставляемых приложением, и т. Д. Для достижения максимальной производительности можно использовать множество стратегий, и иногда отправка небольших пакетов может быть быстрее, чем ожидание создания большой пакет.
Иногда количество запущенных приложений может потребовать, чтобы операционная система работала быстрее (пока отправляла все, что у нее есть в буфере) вместо насыщения буфера.
Возможно, вы могли бы дать нам более подробную информацию о сценарии, с которым вы работали (например: серверная ОС, приложения, работающие на ней).
источник
По сути, проблема в том, что реализация TCP не знает, что приложение будет делать дальше. Когда серверное приложение выполняет последовательность операций записи, стек не знает, являются ли записи, которые он получил до сих пор, всей последовательностью или только ее частью.
В большинстве случаев серверное приложение выполняет запись в буфер быстрее, чем сетевой стек может его очистить. Таким образом, буфер заполнен и выходят полноразмерные пакеты.
Но иногда что-то еще замедляет работу серверного приложения. Возможно, ожидание чтения диска на перегруженном дисковом массиве или что-то в этом роде. Таким образом, буфер очищается, и сетевой стек должен выбирать между отправкой меньшего пакета (больше накладных расходов) или ожиданием данных, которые могут никогда не прийти (добавляя задержку).
источник
Если вы посмотрите на кадр 34, вы увидите, что сервер передал буфер 32 КБ и что бит PSH установлен. Если вы посмотрите на 82, вы увидите то же самое, 32 кБ от предыдущего бита PSH. Пакет 52 имеет бит PSH, хотя отклик был меньше 2 КБ.
Бит PSH обычно устанавливается стеком TCP для последнего сегмента PDU приложения, записанного в сеть. Таким образом, приложение использует буфер 32 КБ, а когда данных много, записывает их в сокет TCP 32 КБ за раз. Когда данных меньше, как в кадрах 51-52, это происходит потому, что приложение записало эту запись первой в ответе, и это было всего 1820 байт.
Обратите внимание, что приложение, на которое я ссылаюсь, на самом деле может быть не самим серверным приложением, а некоторым промежуточным программным обеспечением, таким как виртуальная машина Java (JVM) или чем-то еще Из содержимого данных не ясно, почему был отправлен этот 1820-байтовый PDU, возможно, в то время буфер 32 КБ не был доступен?
Дело в том, что это не должно иметь значения, нет существенного снижения производительности.
источник