Проблема передачи данных в сети сокетами 2.0

Общие вопросы, не зависящие от языка реализации.

Модераторы: Duncon, Hawk, Romeo, Eugie

Ответить
TCoder
Сообщения: 9
Зарегистрирован: 16 июл 2007, 00:20
Контактная информация:

Проблема следующего типа:

Есть сервер, способный поддерживать большое количество клиентов. Когда передача данных идет только от одного клиента, все пучком. При испытаниях заставил всех клиентов высылать постоянно данные. Стал наблюдаться эффект разрыва данных. Т.e. данные от клиента приходят по частям, причем каждая часть приходит, как новый пакет. Я использовал два решения этой проблемы: передача завершающего символа или передача в первых двух байтах истинной длинны пакета. Т.е. пока не будет найден оконечный символ, каждая новая порция данных добавляется в один буфер. И также с размером: Принимаю до тех пор, пока истинный размер данных не уравняется с фактическим. Эффект разрыва также наблюдал при передаче длинных пакетов. (мегабайты)

Вопрос:

Есть ли в сокете 2.0 средства, с помощью которых можно распознать, что пакет передается по частям, ну и например то, что он наконец весь пришел. Или это делается именно так, как это сделал я? Спрашиваю потому, что клиент после отправки генерирует таки сообщения, которые сигнализируют о разрыве пакета, а также о том, что все полностью доставлено.

PS

Это наблюдалось на VB. Будет ли такая же проблема в C++, или там все доведено до ума? Просто у меня возникает мнение, что пакеты могут разбиваться на части не на уровне API, а на уровне VB.

Вообщем, кто что об этом знает, пожалста помогите. У меня на данный момент нет возможности испытать сервер в условиях локальной сети. А на виртуалке, как ни странно, все это по другому работает. Иногда даже без всяких разрывов.

Заранее спасибо. Новичок TCoder.
Alezis
Сообщения: 98
Зарегистрирован: 16 авг 2004, 01:10
Откуда: Минск
Контактная информация:

Насколько я понял у тебя штатное поведение, т.е. при увеличении нагрузки происходит сегментация передаваеых данных. А всё потому что TCP/IP стек при приёме паектов "знает" какой байт должен идти за каким с помощью окна приёма. т.е. если у тебя 2 клиента конектятся и передают данные то допустим сначала пришло несколько байт для 1 клиента, а затем для 2 весь пакет и только потом для 1 всё остальное, вот тебе и разрывы. И покуда приходит пакет для 2 ты уже считал из буфера данные для 1 клиента. Кроме того надо учесть что в локальная сеть это не localhost, а Инет совсем не локальная сеть, т.е. потеря пакетов в Инете насравнима больше чем в локальной сети, посему и пакеты могут приходить с опозданием.
надо просто корректно их собирать при приёме вот и всё.
TCoder
Сообщения: 9
Зарегистрирован: 16 июл 2007, 00:20
Контактная информация:

Alezis писал(а):Насколько я понял у тебя штатное поведение, т.е. при увеличении нагрузки происходит сегментация передаваеых данных. А всё потому что TCP/IP стек при приёме паектов "знает" какой байт должен идти за каким с помощью окна приёма. т.е. если у тебя 2 клиента конектятся и передают данные то допустим сначала пришло несколько байт для 1 клиента, а затем для 2 весь пакет и только потом для 1 всё остальное, вот тебе и разрывы. И покуда приходит пакет для 2 ты уже считал из буфера данные для 1 клиента. Кроме того надо учесть что в локальная сеть это не localhost, а Инет совсем не локальная сеть, т.е. потеря пакетов в Инете насравнима больше чем в локальной сети, посему и пакеты могут приходить с опозданием.
надо просто корректно их собирать при приёме вот и всё.
То, что ты описал, уважаемый Alezis, уже сказано в моем вопросе.... Сам вопрос заключается в том, как определить, что передача пакета не завершена... еще раз повторяюсь, сегменты пакета - приходят как два разных пакета... И этот вопрос я решил только одним методом: в конце данных вышивать специальный код.... при отсутствии которого на приеме начинается буферизация и склеивание данных до тех пор пока код о конце данных не появится в одном из сегметлв... но все равно спасибо за ответ.
Alezis
Сообщения: 98
Зарегистрирован: 16 авг 2004, 01:10
Откуда: Минск
Контактная информация:

TCoder писал(а):То, что ты описал, уважаемый Alezis, уже сказано в моем вопросе.... Сам вопрос заключается в том, как определить, что передача пакета не завершена... еще раз повторяюсь, сегменты пакета - приходят как два разных пакета... И этот вопрос я решил только одним методом: в конце данных вышивать специальный код.... при отсутствии которого на приеме начинается буферизация и склеивание данных до тех пор пока код о конце данных не появится в одном из сегметлв... но все равно спасибо за ответ.
Получается немного неопнял вопрос. :-)
получается что в итоге тебе надо сделать пакет структурным, что собственно ты и сделал, т.е. по каким то признакам CRC, тэгов, специальный код и прочее определять что пришёл пакет полностью или это часть другого пакета. По другому мне видится никак.
Аватара пользователя
OHara
Сообщения: 7
Зарегистрирован: 27 ноя 2007, 12:31

To TCoder: ты все правильно делаешь. Правда, не сказал, как написан твой сервер для обработки клиентов, какой протокол используется (могут быть варианты как в первом, так и втором случае).
Резюмируя, хочу сказать, что надежно будет работать такой алгоритм (при условии TCP):
1. все передаваемые сообщения надо формализовать, то есть сначала идет заголовок, где есть, например, тип сообщения и размер дополнительных данных, которые следуют за заголовком.
2.сначала recv ожидает приход кол-ва байт = размеру заголовка, а затем, если размер доп. данных != 0, то дочитываешь, столько, сколько необходимо.

И так, между прочим, вопрос, а как у тебя обрабатываются клиенты?
Ответить