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. ПО предназначено для работы в составе АСУТП и никакой администратор не изменит настройки маршрутизатора как минимум без моего ведома
подгонка под размер ethernet кадра было выполнено с целью повышения коэффициэнта полезной загрузки сети — чтоб мои данные составляли большую часть пакета.
кстати отвечал я только на вторую часть вопроса Фрагментация пакетов TCP, кто как избавляется, да и то только потому, что с этой самой фрагментацией успешно справился, причём проверял не только на qnet`е, но и на tcp. |
|
klen |
Отправлено: 29.09.2004, 07:13 |
|
Машинист паровоза
Группа: Участник
Сообщений: 239
|
QUOTE (Георгий @ 28/09/2004, 22:56) | ... и никакой администратор не изменит настройки маршрутизатора как минимум без моего ведома |
Это здорово. |
|
Konstantine |
Отправлено: 29.09.2004, 09:00 |
|
Мастер участка
Группа: Модератор
Сообщений: 545
|
QUOTE | кстати отвечал я только на вторую часть вопроса Фрагментация пакетов TCP, кто как избавляется, да и то только потому, что с этой самой фрагментацией успешно справился, причём проверял не только на qnet`е, но и на tcp. |
Ну вообще-то да, я спрашивал про то как с этим работают другие..., но и информация klen оказалась достаточно интересной...
хотя протокол TCP не может ПОТЕРЯТЬ пакеты и не может их переставить местами... они придут в строго правильной последовательности или выдаст ошибку передатчику
именно пронимая переданныю информацию как поток, имеющий токо начало (при запуске приложения) и разрабатывался мой алгоритм:
в его основе лежит то, что в начале сообщения я передаю его размер, который может лежать в нек. пределах, и создаю буфер, который в последствии наполняю, и пока не наполню — никуда... понимаю этот метод может использоваться с сообщениями среднего размера (у меня до 65 кБ), но работает, и по идее должен работать в любой среде передачи и с разными размерами кадров...
продолжаю выслушивать, кто как ещё с этим справляется!
|
|