Модераторы: feodorv

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Фрагментация TCP, Вопрос к знающим 
:(
    Опции темы
REZiaMIX
Дата 29.11.2008, 02:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 346
Регистрация: 3.11.2007

Репутация: нет
Всего: 4



Все говорят , что в TCP пакет может прийти как угодно , т.е. разбит на части. 
Часто ли Вы встречали это на практике , и каковы условия такого поведения?
Надо ли программно как-то обрабатывать фрагментацию?(не превышать MTU например)

В вики написано : 
Цитата

В отличие от UDP, гарантирует, что приложение получит данные точно в такой же последовательности, в какой они были отправлены, и без потерь.

Так ли это?

Условия:
Клиент и сервер могут находится между большим кол-вом маршрутизаторов.

Всем заранее спасибо за ответы.



--------------------
user posted image
PM MAIL   Вверх
J0ker
Дата 29.11.2008, 05:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 986
Регистрация: 17.9.2008

Репутация: 1
Всего: 14



Цитата(REZiaMIX @  29.11.2008,  02:26 Найти цитируемый пост)
Все говорят , что в TCP пакет может прийти как угодно , т.е. разбит на части.

нет
смысл в том, что разбиение потока на пакеты при отправлении чаще всего от вас не зависит, а зависит от настроек стека протоколов

Цитата(REZiaMIX @  29.11.2008,  02:26 Найти цитируемый пост)
Часто ли Вы встречали это на практике

постоянно

Цитата(REZiaMIX @  29.11.2008,  02:26 Найти цитируемый пост)
и каковы условия такого поведения

настройки системы с которой отправляются данные плюс естественное ограничение накладываемое протоколами

Цитата(REZiaMIX @  29.11.2008,  02:26 Найти цитируемый пост)
Надо ли программно как-то обрабатывать фрагментацию?(не превышать MTU например)

в общем случае нет

Цитата(REZiaMIX @  29.11.2008,  02:26 Найти цитируемый пост)
Так ли это?

абсолютно



--------------------
user posted image
PM MAIL   Вверх
REZiaMIX
Дата 29.11.2008, 17:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 346
Регистрация: 3.11.2007

Репутация: нет
Всего: 4



Т.е мне надо просто забивать на расклеенные пакеты , и обрабатывать только правильно пришедшие?


--------------------
user posted image
PM MAIL   Вверх
Lazin
Дата 29.11.2008, 18:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

Репутация: 5
Всего: 154



нет, если ты принимаешь данные синхронно, то тебе будет приходить все сразу(то что уже получено от сервера), например сервер отправляет данные, блоками по 0х1000 байт, тогда ты просто передешь в ф-ю recv указатель на принимающий буфер и говоришь что нужно принять 0x1000 байт если данные уже получены, то ф-я просто скопирует их в  буфер, если нет, то она подождет пока они не прийдут.
если принимаешь данные асинхронно, то ты будешь получать не сразу столько, сколько попросишь, а столько, сколько уже пришло, а приходить оно может по частям и тебе нужно будет эти части объединять... как-то так smile 
PM MAIL Skype GTalk   Вверх
J0ker
Дата 29.11.2008, 18:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 986
Регистрация: 17.9.2008

Репутация: 1
Всего: 14



Цитата(Lazin @ 29.11.2008,  18:03)
нет, если ты принимаешь данные синхронно, то тебе будет приходить все сразу(то что уже получено от сервера), например сервер отправляет данные, блоками по 0х1000 байт, тогда ты просто передешь в ф-ю recv указатель на принимающий буфер и говоришь что нужно принять 0x1000 байт если данные уже получены, то ф-я просто скопирует их в  буфер, если нет, то она подождет пока они не прийдут.
если принимаешь данные асинхронно, то ты будешь получать не сразу столько, сколько попросишь, а столько, сколько уже пришло, а приходить оно может по частям и тебе нужно будет эти части объединять... как-то так smile

Lazin, не вводи человека в заблуждение
синхронная и асинхронная ОБРАБОТКА никакого отношения к recv не имеет
сервер не отправляет данные блоками - он отправляет поток
то, что сервер вызвал функцию send на 1000 байт не означает что данные будут запихнуты в один IP пакет - они могут быть как угодно фрагментированы на этапе отправки
и функция recv никогда не ждет, пока придет весь размер, указанный в размере буфера - она примет сколько есть на данный момент - тут существует только различие в блокирующем сокете и не блокирующем - блокирующий заблокируется если данный вообще нет и разблокируется если будет хотя-бы один байт (или закрывающий соединение пакет), а не блокирующий если нет данных просто выйдет со статусом ошибки EWOULDBLOCK



--------------------
user posted image
PM MAIL   Вверх
REZiaMIX
Дата 29.11.2008, 18:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 346
Регистрация: 3.11.2007

Репутация: нет
Всего: 4



Цитата(Lazin @ 29.11.2008,  18:03)
нет, если ты принимаешь данные синхронно, то тебе будет приходить все сразу(то что уже получено от сервера), например сервер отправляет данные, блоками по 0х1000 байт, тогда ты просто передешь в ф-ю recv указатель на принимающий буфер и говоришь что нужно принять 0x1000 байт если данные уже получены, то ф-я просто скопирует их в  буфер, если нет, то она подождет пока они не прийдут.
если принимаешь данные асинхронно, то ты будешь получать не сразу столько, сколько попросишь, а столько, сколько уже пришло, а приходить оно может по частям и тебе нужно будет эти части объединять... как-то так smile

Т.е. если я заказываю асинхронно прием 512 байт данных , то вполне может прийти меньше?


--------------------
user posted image
PM MAIL   Вверх
J0ker
Дата 29.11.2008, 18:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 986
Регистрация: 17.9.2008

Репутация: 1
Всего: 14



Цитата(REZiaMIX @ 29.11.2008,  17:20)
Т.е мне надо просто забивать на расклеенные пакеты , и обрабатывать только правильно пришедшие?

вам нужно собирать поток
все пришедшие пакеты ПРАВИЛЬНЫ - они просто разбиты на несколько вызовов функции recv
поймите - в TCP НЕТ пакетов - это поток, просто он на принимающей стороне появляется очень медленно (по сравнению с возможностью обработки) - и его надо ждать путем множественного вызова recv - как только вы СОБЕРЕТЕ кусок который можете обработать - вы его обрабатываете и собираете следующий кусок

Добавлено через 1 минуту и 9 секунд
Цитата(REZiaMIX @ 29.11.2008,  18:32)
Цитата(Lazin @ 29.11.2008,  18:03)
нет, если ты принимаешь данные синхронно, то тебе будет приходить все сразу(то что уже получено от сервера), например сервер отправляет данные, блоками по 0х1000 байт, тогда ты просто передешь в ф-ю recv указатель на принимающий буфер и говоришь что нужно принять 0x1000 байт если данные уже получены, то ф-я просто скопирует их в  буфер, если нет, то она подождет пока они не прийдут.
если принимаешь данные асинхронно, то ты будешь получать не сразу столько, сколько попросишь, а столько, сколько уже пришло, а приходить оно может по частям и тебе нужно будет эти части объединять... как-то так smile

Т.е. если я заказываю асинхронно прием 512 байт данных , то вполне может прийти меньше?

см. выше - нет никакого "синхронно-асинхронно"


--------------------
user posted image
PM MAIL   Вверх
REZiaMIX
Дата 29.11.2008, 18:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 346
Регистрация: 3.11.2007

Репутация: нет
Всего: 4



Хм , читаю MSDN: 
Цитата

MSG_WAITALL    The receive request will complete only when one of the following events occurs:

    * The buffer supplied by the caller is completely full.
    * The connection has been closed.
    * The request has been canceled or an error occurred.

Note that if the underlying transport does not support MSG_WAITALL, or if the socket is in a non-blocking mode, then this call will fail with WSAEOPNOTSUPP. Also, if MSG_WAITALL is specified along with MSG_OOB, MSG_PEEK, or MSG_PARTIAL, then this call will fail with WSAEOPNOTSUPP. This flag is not supported on datagram sockets or message-oriented CO sockets.

Т.е. с этим флагом пакет по идее должен прийти полностью , как заказанно?!?!?.
Только если сокет в блокирующем режиме ...

Не пойму , кто прав кто нет.

Это сообщение отредактировал(а) REZiaMIX - 29.11.2008, 18:43


--------------------
user posted image
PM MAIL   Вверх
J0ker
Дата 29.11.2008, 18:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 986
Регистрация: 17.9.2008

Репутация: 1
Всего: 14



Цитата(REZiaMIX @  29.11.2008,  18:38 Найти цитируемый пост)
Т.е. с этим флагом пакет по идее должен прийти полностью , как заказанно?!?!?.
Только если сокет в блокирующем режиме ...

забудьте про пакеты
этот флаг указывает блокирующему сокету сидеть в recv пока буфер который вы ему передали не будет полностью заполнен (либо не случится других неприятностей)
к пакетам это отношения не имеет
еще раз объясняю
если вы на одной стороне вызвали send на 1000 байт, то это не означает, что уйдет пакет на 1000 байт - может уйти десять пакетов разной длины - это решает стек протоколов
если вы на принимающей стороне вызвали recv на 1000 байт на блокирующей сокет - то recv выйдет с ЛЮБЫМ количеством принятых байт меньше или равно 1000, либо будет заблокирован если вы указали MSG_WAITALL пока не заполнит 1000 байт - но это не имеет отношения к пакетам

Это сообщение отредактировал(а) J0ker - 29.11.2008, 18:51


--------------------
user posted image
PM MAIL   Вверх
REZiaMIX
Дата 29.11.2008, 19:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 346
Регистрация: 3.11.2007

Репутация: нет
Всего: 4



Цитата(J0ker @ 29.11.2008,  18:51)
забудьте про пакеты
этот флаг указывает блокирующему сокету сидеть в recv пока буфер который вы ему передали не будет полностью заполнен (либо не случится других неприятностей)
к пакетам это отношения не имеет
еще раз объясняю
если вы на одной стороне вызвали send на 1000 байт, то это не означает, что уйдет пакет на 1000 байт - может уйти десять пакетов разной длины - это решает стек протоколов
если вы на принимающей стороне вызвали recv на 1000 байт на блокирующей сокет - то recv выйдет с ЛЮБЫМ количеством принятых байт меньше или равно 1000, либо будет заблокирован если вы указали MSG_WAITALL пока не заполнит 1000 байт - но это не имеет отношения к пакетам

Не пакет , а скажем целиковый буффер отправленный другой стороной) 
Вот это мне и требовалось услышать


--------------------
user posted image
PM MAIL   Вверх
J0ker
Дата 29.11.2008, 19:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 986
Регистрация: 17.9.2008

Репутация: 1
Всего: 14



тока не забудьте, что с разрешенными сигналами или OOB пакетами recv может наплевать на MSG_WAITALL


--------------------
user posted image
PM MAIL   Вверх
REZiaMIX
Дата 29.11.2008, 19:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 346
Регистрация: 3.11.2007

Репутация: нет
Всего: 4



Цитата(J0ker @ 29.11.2008,  19:12)
тока не забудьте, что с разрешенными сигналами или OOB пакетами recv может наплевать на MSG_WAITALL

Знаю. Спасибо)


--------------------
user posted image
PM MAIL   Вверх
MAKCim
Дата 30.11.2008, 11:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 6
Всего: 207



Цитата(J0ker @  29.11.2008,  18:30 Найти цитируемый пост)
блокирующий заблокируется если данный вообще нет и разблокируется если будет хотя-бы один байт

ну не совсем
точнее количество байт, нужное для разблокирования recv, не фиксировано и может быть установлено
по-умолчанию 1 байт  smile 




--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
Олег2005
Дата 30.11.2008, 14:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Завсегдатай
Сообщений: 421
Регистрация: 26.5.2005
Где: Рига Латвия

Репутация: 6
Всего: 11



Цитата(MAKCim @  30.11.2008,  10:15 Найти цитируемый пост)
не фиксировано и может быть установлено
по-умолчанию 1 байт  smile 

Может быть? Оно уже установлено в 1 байт:
Цитата
SO_RCVLOWAT, SO_SNDLOWAT 
Этими опциями регулируется минимальное количество данных в буфере приема/передачи, на которое реагирует функция select(). Для приемного буфера модуля TCP по умолчанию это 1 байт. Для буфера передачи - это минимально допустимое количество свободного пространства, когда сокет будет готов для передачи, для TCP-сокетов это обычно 2048.

Так как посылки keepalive содержат ровно 1 байт smile 

Это сообщение отредактировал(а) Олег2005 - 30.11.2008, 14:41
PM MAIL WWW MSN   Вверх
MAKCim
Дата 30.11.2008, 18:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 6
Всего: 207



Цитата(Олег2005 @  30.11.2008,  14:39 Найти цитируемый пост)
Может быть? Оно уже установлено в 1 байт:

так я не понял, где я не прав?  smile 


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
Олег2005
Дата 30.11.2008, 21:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Завсегдатай
Сообщений: 421
Регистрация: 26.5.2005
Где: Рига Латвия

Репутация: 6
Всего: 11



Цитата(MAKCim @  30.11.2008,  10:15 Найти цитируемый пост)
может быть установлено
по-умолчанию 1 байт  smile 

Не может - а уже установлено smile 
PM MAIL WWW MSN   Вверх
MAKCim
Дата 30.11.2008, 22:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 6
Всего: 207



Цитата(Олег2005 @  30.11.2008,  21:33 Найти цитируемый пост)
Не может - а уже установлено

так я и сказал, что по-умолчанию 1
но в общем случае это не фиксированная константа
значение можно менять, в этом смысле


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
Страницы: (2) [Все] 1 2 
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Сети | Следующая тема »


 




[ Время генерации скрипта: 0.0602 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.