Размеры пакетов в потоке TCP

10

Я являюсь сетевым трафиком и хочу разделить каждый сеанс 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 
Вадим
источник
Причин может быть так много ... Размер окна может быть слишком мал (хотя в вашем случае это маловероятно), может быть недостаточно данных для отправки (вывод генерируется скриптом?), Программное обеспечение, генерирующее данные, может явно промыли его и т. д.
Сандер Штеффанн
@SanderSteffann, размер окна не имеет значения, аки приходят с довольно регулярными интервалами. Весь ответ представляет собой javascript, поэтому я не думаю, что он генерируется другим скриптом.
Вадим
@vadim, не могли бы вы опубликовать скриншот или, что лучше, гиперссылку на pcap с полезной нагрузкой 1080 байт?
Майк Пеннингтон
@MikePennington - спасибо за ваш вклад, я предоставлю ссылку на файл pcap через несколько часов.
Вадим
@MikePennington - я добавил ссылку на файл pcap, который демонстрирует это.
Вадим

Ответы:

6

Уровень TCP использует алгоритм Nagle для буферизации трафика (он отправляет меньше больших пакетов вместо более маленьких пакетов ... что делает его более эффективным); у приложения есть способ сказать «отправить сейчас». Вы видите это в заголовке TCP с флагом, называемым битом PSH (push). Пока бит задается стеком, отправка выполняется по запросу приложения.

Так что это намеренное и нормальное поведение.

fredpbaker
источник
Уточнение ... Приложения не имеют прямого контроля над битом PSH ...
Майк Пеннингтон,
Совершенно верно, было то, что ДОЛЖНО быть сделано в оригинальном RFC и что было сделано с winsock и сокетами
fredpbaker
посмотрев на pcap, очень маловероятно, что веб-сервер установит PSH на трафик OP
Майк Пеннингтон,
3

Размер пакета зависит от того, как приложение и / или ОС буферизируют и отправляют сетевые данные. Если приложение и / или ОС решают отправить данные после того, как 1080 байт находятся в буфере, то пакет будет 1080 байтов (плюс заголовки). Для этого может быть много причин. В вашем случае вам придется искать исходный код веб-сервера и / или сетевой стек ОС.

Себастьян Визингер
источник
Я вижу много пакетов с максимальным размером и только этот с меньшим размером, так что это не какой-то тип по умолчанию. Может ли это быть сбой сервера - он застрял на чем-то другом из-за задержки, которой было достаточно для сетевого стека, чтобы решить отправить то, что было в буфере?
Вадим
Конечно, могло быть что угодно. Невозможно сказать, не отладив сервер и ОС, на которой он работает. Но ничего страшного в ИМХО нет.
Себастьян Визингер
Я не встревожен, это только казалось странным, и я хотел узнать, есть ли что-то еще, чем это.
Вадим
1
Если у вас есть wireshark, посмотрите в TCP-заголовке 1080 пакетов бит PSH (push). Это стек приложений, который говорит, что отправьте эти данные сейчас.
fredpbaker
1
Смотрите выше, это стек TCP в большинстве случаев
fredpbaker
1

Размер пакета определяется ОС (в целом) и связан с буферами, объемом данных, предоставляемых приложением, и т. Д. Для достижения максимальной производительности можно использовать множество стратегий, и иногда отправка небольших пакетов может быть быстрее, чем ожидание создания большой пакет.

Иногда количество запущенных приложений может потребовать, чтобы операционная система работала быстрее (пока отправляла все, что у нее есть в буфере) вместо насыщения буфера.

Возможно, вы могли бы дать нам более подробную информацию о сценарии, с которым вы работали (например: серверная ОС, приложения, работающие на ней).

woliveirajr
источник
0

По сути, проблема в том, что реализация TCP не знает, что приложение будет делать дальше. Когда серверное приложение выполняет последовательность операций записи, стек не знает, являются ли записи, которые он получил до сих пор, всей последовательностью или только ее частью.

В большинстве случаев серверное приложение выполняет запись в буфер быстрее, чем сетевой стек может его очистить. Таким образом, буфер заполнен и выходят полноразмерные пакеты.

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

Питер Грин
источник
0

Если вы посмотрите на кадр 34, вы увидите, что сервер передал буфер 32 КБ и что бит PSH установлен. Если вы посмотрите на 82, вы увидите то же самое, 32 кБ от предыдущего бита PSH. Пакет 52 имеет бит PSH, хотя отклик был меньше 2 КБ.

Бит PSH обычно устанавливается стеком TCP для последнего сегмента PDU приложения, записанного в сеть. Таким образом, приложение использует буфер 32 КБ, а когда данных много, записывает их в сокет TCP 32 КБ за раз. Когда данных меньше, как в кадрах 51-52, это происходит потому, что приложение записало эту запись первой в ответе, и это было всего 1820 байт.

Обратите внимание, что приложение, на которое я ссылаюсь, на самом деле может быть не самим серверным приложением, а некоторым промежуточным программным обеспечением, таким как виртуальная машина Java (JVM) или чем-то еще Из содержимого данных не ясно, почему был отправлен этот 1820-байтовый PDU, возможно, в то время буфер 32 КБ не был доступен?

Дело в том, что это не должно иметь значения, нет существенного снижения производительности.

marctxk
источник