C++ Builder
| Главная | Уроки | Статьи | FAQ | Форум | Downloads | Литература | Ссылки | RXLib | Диски |

 
Фрагментация пакетов TCP, кто как избавляется
Konstantine
Отправлено: 27.09.2004, 09:10


Мастер участка

Группа: Модератор
Сообщений: 545



ПисАл прогу, которая использует ServerSocket и ClientSocket, и обнаружил что при передаче буфера в неск. кБ, происходит его фрагментация — в ответной программе он вызывает OnRead несколько раз!

Проверил — написАл две проги, клиент — соединяется и передаёт серверу 1 МБ данных, а сервер их принимает и выводит на Мемо (консоль) сколько принято, и считывает их (для освобождения буфера). Проверка показала, что пакеты приходят по 2, 4, и 8 кБ... причём случайным образом...

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

P.S.: То что я написАл для устранения — довольно сложный алгоритм, причём он ориентирован на то, что принимаются данные только с одного клиента.

Может кто знает проше метод?
Георгий
Отправлено: 27.09.2004, 10:23


Почетный железнодорожник

Группа: Модератор
Сообщений: 874



у меня потоковые данные и их разбивал на порции по 1500 байт — под размер кадра ethernet подгонял
Konstantine
Отправлено: 27.09.2004, 10:57


Мастер участка

Группа: Модератор
Сообщений: 545



а меньше 1500 не разбивает?
напр. при загруженной сети
Георгий
Отправлено: 27.09.2004, 20:29


Почетный железнодорожник

Группа: Модератор
Сообщений: 874



фрагментация пакетов выполняется до размера <= размеру кадра передающей среды:
ethernet fastnet (10/100Mb) — ~1500 byte
frame relay — (точно не помню, но кажется) 200byte

от загрузки передающей среды размер кадра ethernet не зависит.

это была теория, а на практике это проверялось на свитче 3com (модель могу завтра/послезавтра сказать) и 24 узлах. в статистике, ведомой коммутатором, фрагментированных пакетов небыло.
Konstantine
Отправлено: 28.09.2004, 08:29


Мастер участка

Группа: Модератор
Сообщений: 545



QUOTE (Георгий @ 27/09/2004, 21:31)
... в статистике, ведомой коммутатором, фрагментированных пакетов небыло ...

а при каких пакетах?

P.S.: Ну Frame relay у меня не будет — токо Ethernet
klen
Отправлено: 28.09.2004, 18:41


Машинист паровоза

Группа: Участник
Сообщений: 239



Мужики привет.
Я наверно для вас Америку открою и сану колумбом:) Ктонибудь хоть раз читал RFC 1122,793, и иже с ними связанными. Может вас это огорчит но TCP — потоковый протокол!! это надо фибрами понимать. Это ознасает что в прочесе доставки пользовательских данных протокол не делает никаких предположений на тему как то "пакет" "порция" и тд, с точностью до байта. И проблема не в быстодействии машин а в основопологающих принципах. Еслибы протокол предполагал о наличии порций(пакетов) то ТСР никак не удалось бы добится эфективного совмешения противоречивых требований производительности и надежности. Я всегда привожу такой пример тем кто сталкивается с описанной проблемой (это у всех бывает но не увсех проходит, товарищи которые не наступают на эти грабли в локальных сетях уверены что все логика приложения правильно продумана а прилагуха класно работает, но стоит им выйти с такойт паделкой в интернет, на на наших линиях — катахизис полный) — представте что вы передаете блок X кб , он передается по каналу передачи и часть теряется, что обычно в интернент сетях. Вот каким образом протокол догадается что блок кончился??? Мне трудно обьяснить здесь все сразу, у мнея 2 месяца ушло на разбор TCP кстате как оказалось TClientSoket особенно TServerSoket не вполне адекватны. Сама Борланд категорически рекомендует их не использовать!

В общем устал я писать, буду краток.
1. То что Вы получили — абсолютно правильная и логичная ситуация в контексте ТСР — это байтовый пток без начала и конца с точки зрения агентов!!!
2. ЕСЛИ ПРИЕМНИК ДЕЛАЕТ ХОТЬ КАКИЕТО ПРЕДПОЛОЖЕНИЯ О СТРУКТУРЕ ПОТОКА ПО СЧИТЫВАЕМЫМ ФРАГМЕНТА — ПРИЛОЖЕНИЕ СПРОЕКТИРОВАНО НЕ ПРОВИЛЬНО И ЕГО НАДА ПЕРДЕЛАТЬ ПОКА НЕ ПОЗДНО! (Ваш покорный слуга сам 2 недели потратил иза такойже ошибки чтоб все заново переделать)
3. Анализ границ данных в рамках модели ТСР ложится на агентов.
а) Использовать структуры пользовательского пакета(не пакета ТСР) в заголовке которого указывают длинну передаваймых данных
б) Использовать синхронные вызовы readn или родственные ей которые блокируют поток до записи ядром ОС пользователского буфера заданным числом байт — например размер пользю пакета.
в) Снабжение потока данныз маркерами границ.

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

2_Георгий.
Вы это зря под пакет подганяете — теже яйца вид сбоку. Пример: у меня на кафедре стоит маршрутизатор  — он связан с моршрутизатором другой кафедры.....а у них нах своя сеть на спарках и интерпрайзах, и мой друг — администратор сети плевал на мои пакетиы по 1500байт взял и настроил размер 1234 байт и живет припеваючи — все мои проги перестанут работать! ПОТОК БАЙТ И БОЛЬШЕ НИЧЕГО С ТОЧКИ ЗРЕНИЯ ПОЛЬЗОВАТЕЛЯ!!!

Удачи. надеюсь Вам это поможет.

Отредактировано klen — 28/09/2004, 19:50
Георгий
Отправлено: 28.09.2004, 21:54


Почетный железнодорожник

Группа: Модератор
Сообщений: 874



спасибо. но есть одно уточнение
QUOTE
2_Георгий.
Вы это зря под пакет подганяете — теже яйца вид сбоку. Пример: у меня на кафедре стоит маршрутизатор — он связан с моршрутизатором другой кафедры.....а у них нах своя сеть на спарках и интерпрайзах, и мой друг — администратор сети плевал на мои пакетиы по 1500байт взял и настроил размер 1234 байт и живет припеваючи — все мои проги перестанут работать! ПОТОК БАЙТ И БОЛЬШЕ НИЧЕГО С ТОЧКИ ЗРЕНИЯ ПОЛЬЗОВАТЕЛЯ!!!

сижу я под qnx4 и обычно использую qnet-fleet. ПО предназначено для работы в составе АСУТП и никакой администратор не изменит настройки маршрутизатора как минимум без моего ведома smile.gif
подгонка под размер ethernet кадра было выполнено с целью повышения коэффициэнта полезной загрузки сети — чтоб мои данные составляли большую часть пакета.
кстати отвечал я только на вторую часть вопроса Фрагментация пакетов TCP, кто как избавляется, да и то только потому, что с этой самой фрагментацией успешно справился, причём проверял не только на qnet`е, но и на tcp.
klen
Отправлено: 29.09.2004, 07:13


Машинист паровоза

Группа: Участник
Сообщений: 239



QUOTE (Георгий @ 28/09/2004, 22:56)
... и никакой администратор не изменит настройки маршрутизатора как минимум без моего ведома smile.gif

Это здорово.
Konstantine
Отправлено: 29.09.2004, 09:00


Мастер участка

Группа: Модератор
Сообщений: 545



QUOTE
кстати отвечал я только на вторую часть вопроса Фрагментация пакетов TCP, кто как избавляется, да и то только потому, что с этой самой фрагментацией успешно справился, причём проверял не только на qnet`е, но и на tcp.


Ну вообще-то да, я спрашивал про то как с этим работают другие..., но и информация klen оказалась достаточно интересной...

хотя протокол TCP не может ПОТЕРЯТЬ пакеты и не может их переставить местами... они придут в строго правильной последовательности или выдаст ошибку передатчику

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

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

продолжаю выслушивать, кто как ещё с этим справляется!

Вернуться в Вопросы программирования в C++Builder