| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > C/C++: Сети > Фрагментация TCP |
| Автор: REZiaMIX 29.11.2008, 02:26 | ||
| Все говорят , что в TCP пакет может прийти как угодно , т.е. разбит на части. Часто ли Вы встречали это на практике , и каковы условия такого поведения? Надо ли программно как-то обрабатывать фрагментацию?(не превышать MTU например) В вики написано :
Так ли это? Условия: Клиент и сервер могут находится между большим кол-вом маршрутизаторов. Всем заранее спасибо за ответы. |
| Автор: REZiaMIX 29.11.2008, 17:20 |
| Т.е мне надо просто забивать на расклеенные пакеты , и обрабатывать только правильно пришедшие? |
| Автор: Lazin 29.11.2008, 18:03 |
| нет, если ты принимаешь данные синхронно, то тебе будет приходить все сразу(то что уже получено от сервера), например сервер отправляет данные, блоками по 0х1000 байт, тогда ты просто передешь в ф-ю recv указатель на принимающий буфер и говоришь что нужно принять 0x1000 байт если данные уже получены, то ф-я просто скопирует их в буфер, если нет, то она подождет пока они не прийдут. если принимаешь данные асинхронно, то ты будешь получать не сразу столько, сколько попросишь, а столько, сколько уже пришло, а приходить оно может по частям и тебе нужно будет эти части объединять... как-то так |
| Автор: J0ker 29.11.2008, 18:30 | ||
Lazin, не вводи человека в заблуждение синхронная и асинхронная ОБРАБОТКА никакого отношения к recv не имеет сервер не отправляет данные блоками - он отправляет поток то, что сервер вызвал функцию send на 1000 байт не означает что данные будут запихнуты в один IP пакет - они могут быть как угодно фрагментированы на этапе отправки и функция recv никогда не ждет, пока придет весь размер, указанный в размере буфера - она примет сколько есть на данный момент - тут существует только различие в блокирующем сокете и не блокирующем - блокирующий заблокируется если данный вообще нет и разблокируется если будет хотя-бы один байт (или закрывающий соединение пакет), а не блокирующий если нет данных просто выйдет со статусом ошибки EWOULDBLOCK |
| Автор: REZiaMIX 29.11.2008, 18:32 | ||
Т.е. если я заказываю асинхронно прием 512 байт данных , то вполне может прийти меньше? |
| Автор: J0ker 29.11.2008, 18:35 | ||||||
вам нужно собирать поток все пришедшие пакеты ПРАВИЛЬНЫ - они просто разбиты на несколько вызовов функции recv поймите - в TCP НЕТ пакетов - это поток, просто он на принимающей стороне появляется очень медленно (по сравнению с возможностью обработки) - и его надо ждать путем множественного вызова recv - как только вы СОБЕРЕТЕ кусок который можете обработать - вы его обрабатываете и собираете следующий кусок Добавлено через 1 минуту и 9 секунд
см. выше - нет никакого "синхронно-асинхронно" |
| Автор: REZiaMIX 29.11.2008, 18:38 | ||
Хм , читаю MSDN:
Т.е. с этим флагом пакет по идее должен прийти полностью , как заказанно?!?!?. Только если сокет в блокирующем режиме ... Не пойму , кто прав кто нет. |
| Автор: J0ker 29.11.2008, 18:51 | ||
забудьте про пакеты этот флаг указывает блокирующему сокету сидеть в recv пока буфер который вы ему передали не будет полностью заполнен (либо не случится других неприятностей) к пакетам это отношения не имеет еще раз объясняю если вы на одной стороне вызвали send на 1000 байт, то это не означает, что уйдет пакет на 1000 байт - может уйти десять пакетов разной длины - это решает стек протоколов если вы на принимающей стороне вызвали recv на 1000 байт на блокирующей сокет - то recv выйдет с ЛЮБЫМ количеством принятых байт меньше или равно 1000, либо будет заблокирован если вы указали MSG_WAITALL пока не заполнит 1000 байт - но это не имеет отношения к пакетам |
| Автор: REZiaMIX 29.11.2008, 19:01 | ||
Не пакет , а скажем целиковый буффер отправленный другой стороной) Вот это мне и требовалось услышать |
| Автор: J0ker 29.11.2008, 19:12 |
| тока не забудьте, что с разрешенными сигналами или OOB пакетами recv может наплевать на MSG_WAITALL |
| Автор: REZiaMIX 29.11.2008, 19:22 | ||
Знаю. Спасибо) |
| Автор: MAKCim 30.11.2008, 11:15 | ||
ну не совсем точнее количество байт, нужное для разблокирования recv, не фиксировано и может быть установлено по-умолчанию 1 байт |
| Автор: Олег2005 30.11.2008, 14:39 | ||
Может быть? Оно уже установлено в 1 байт:
Так как посылки keepalive содержат ровно 1 байт |
| Автор: MAKCim 30.11.2008, 18:52 |
так я не понял, где я не прав? |
| Автор: Олег2005 30.11.2008, 21:33 |
Не может - а уже установлено |
| Автор: MAKCim 30.11.2008, 22:34 |
так я и сказал, что по-умолчанию 1 но в общем случае это не фиксированная константа значение можно менять, в этом смысле |