![]() |
|
Модераторы: feodorv |
![]()
|
|
| mad_lollipop |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 12 Регистрация: 5.9.2007 Репутация: нет Всего: нет |
Недавно начал работать с сокетами, использую их в чистом виде, т.е. Сокеты Беркли+AF_INET, SOCK_STREAM, IPPROTO_TCP, потоковые, TCP. Возник вопрос, связанный с функцией recv. Если наш сокет не асинхронный, тогда при вызове этой функции мы ждем, пока во входном буфере сокета не появятся данные присланного пакета. При появлении данных в буфере мы можем обрабатывать полученное. Но вот что интересует больше всего: гарантируется ли полнота присланных данных, т.е. если нам послали 50 байт, то нам их столько и прийдет, или может возникнуть ситуация, когда нам эти 50 байт придут по частям, причем после получения первой части байтов наша программа получит возможность работы не дожидаясь получения следующих частей??? Возможно, все это реализуется на уровне TCP? Или как?
|
|||
|
||||
| jonie |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5613 Регистрация: 21.8.2005 Где: Владимир Репутация: 5 Всего: 118 |
описанная ситуация вполне возможна, и зависит не только от настроек ОС, но и от устройства стека TCP\IP в системе...
а почему это вам должны давать сразу все присланные данные? может их там будет 20 мегабайт... -------------------- Что-то не поняли? -> Напейтесь до зеленых человечков... эта сверхцивилизация Вам поможет... |
|||
|
||||
| J0ker |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 986 Регистрация: 17.9.2008 Репутация: 1 Всего: 14 |
для UDP пакет приходит целиком, если на recv запрошено меньше, то остаток теряется
для TCP возможна фрагментация пакетов (т.к. фактически пакетов нет - это потоковый протокол), при этом данный не теряются, даже когда в recv запрошено меньше имеющегося |
|||
|
||||
| MAKCim |
|
|||
![]() Воін дZэна ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5644 Регистрация: 10.12.2005 Где: Менск, РБ Репутация: 6 Всего: 207 |
ну вообще говоря клиент/сервер обязан сам следить за целостностью данных в рамках протокола т. е нужно читать столько, сколько надо (подразумевает протокол) -------------------- Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі © |
|||
|
||||
| SVN74 |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 740 Регистрация: 5.5.2008 Где: Комсомольск на Дн епре Репутация: 1 Всего: 18 |
Я был столкнулся с подобной проблемой при пересылке больших размеров данных (в МАССИВАХ),
так как массив надо заполнить за один присест, пришлось смастерить свою функцию для полного заполнения массива: Где: RecivedData - Массив данных SizeOfData - Размер массива SizeDataForSpeed - Можно устанавливать любую скорость но не больше размера массива ///////////////////////////////////////////////////////////
Да... При ошибках будет возвращать -1 Это сообщение отредактировал(а) SVN74 - 17.11.2008, 00:21 |
|||
|
||||
| jonie |
|
||||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5613 Регистрация: 21.8.2005 Где: Владимир Репутация: 5 Всего: 118 |
вспоминается тот незабываемый код, что когда-то писал наш офис в тайланде....
опишу пошагово (без обид, с юмором):
-------------------- Что-то не поняли? -> Напейтесь до зеленых человечков... эта сверхцивилизация Вам поможет... |
||||
|
|||||
| SVN74 |
|
||||||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 740 Регистрация: 5.5.2008 Где: Комсомольск на Дн епре Репутация: 1 Всего: 18 |
Ну во первых чтобы использовать эту функцию буфер "RecivedData" заранее должен быть проверен и подготовлен
Как ни странно на скорость влияет ... Признаю... Лишнее... Можно вычеркнуть.
Здесь Ptr изначально void* - приводить не обязательно, иначе была бы ошибка, (проверено).
..................................................................................................................... Несмотря на насмешки, этот код критических ошибок не имеет, конечно эго можно упростить вообще. У меня эта функция скачивает сотнями Ггб в сети и ошибок не возникало, даже когда я ее принудительно садил на ошибки. ..................................................................................................................... Что интересно, как только кто ни будь просит помощи в написании кода - помогать никто практически не хочет, тут я поддерживаю людей, которые помогают, тратя свое время... Но вот (блеснуть своим умом) обсудить чужой код , пускай не доскональный желающих довольно много, что интересно это чаще относится к людям у кого сообщений переваливает за 1000 - такой народ обычно ничего своего не выставляет... БЕЗ ОБИД |
||||||||
|
|||||||||
| REZiaMIX |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 346 Регистрация: 3.11.2007 Репутация: нет Всего: 4 |
Не в тему но: Поддерживаю! -------------------- ![]() |
|||
|
||||
| vinick |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 285 Регистрация: 9.6.2005 Репутация: 6 Всего: 22 |
У тебя исключения бросает только new. Так что никакой очистки не надо.
А теперь представь ситуацию SizeOfData=100, SizeDataForSpeed = 40 и у тебя recv 3 раза подряд прочитает по 40 байт. Потеря 20 байт и выход за границы массива в твоём приложении не критично ;) Влияет, но очень опосредовано. |
|||
|
||||
| jonie |
|
||||||||||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5613 Регистрация: 21.8.2005 Где: Владимир Репутация: 5 Всего: 118 |
Добавлено через 3 минуты и 3 секунды
-------------------- Что-то не поняли? -> Напейтесь до зеленых человечков... эта сверхцивилизация Вам поможет... |
||||||||||
|
|||||||||||
| SVN74 |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 740 Регистрация: 5.5.2008 Где: Комсомольск на Дн епре Репутация: 1 Всего: 18 |
С учетом выше сказанных замечаний упростил свою функцию.
Работает также без проблем. Какие замечания будут?
|
|||
|
||||
| J0ker |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 986 Регистрация: 17.9.2008 Репутация: 1 Всего: 14 |
о
а теперь как мы отличим - сокет закрывают или у нас ошибка? |
|||
|
||||
| SVN74 |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 740 Регистрация: 5.5.2008 Где: Комсомольск на Дн епре Репутация: 1 Всего: 18 |
Ну на практике идет поток (бесконечный) и эта функция получает определенный размер данных, если поток завершится раньше, то сработает ошибка на “ресиве” и возвращается -1. Ну конечно передающий код не должен быть с перерывами, так как будет ожидание пока не дойдут все данные... |
|||
|
||||
| J0ker |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 986 Регистрация: 17.9.2008 Репутация: 1 Всего: 14 |
вы меня не поняли
как определить - сокет закрыли с той стороны или у нас чего-то сломалось? |
|||
|
||||
| SVN74 |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 740 Регистрация: 5.5.2008 Где: Комсомольск на Дн епре Репутация: 1 Всего: 18 |
По такой причине, может ожидать до ~ 30 сек и срабатывает ошибка, - (опробовано), если конечно разрыва вообще нет будет ждать вечно, ну я думаю это практически не реально, практически всегда сокет разрывается. Это сообщение отредактировал(а) SVN74 - 20.11.2008, 21:57 |
|||
|
||||
![]()
|
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | C/C++: Сети | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |