![]() |
Модераторы: feodorv |
![]() ![]() ![]() |
|
En_t_end |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2074 Регистрация: 4.12.2004 Репутация: нет Всего: 20 |
Занимаюсь разработкой класса инкапсулирующего возможности winsocket'ов. Нужно добиться подобной абстракции:
Псевдокод:
Где >> и << операторы отправки и примема данных соотвественно. То есть мне надо достичь потоковой гибкости и простоты. Просто мысли разбегаются... вообще как примерно должен выглядеть такой класс ? Если можно, то в общих чертах. |
|||
|
||||
Mad |
|
|||
Опытный ![]() ![]() Профиль Группа: Эксперт Сообщений: 656 Регистрация: 18.10.2004 Где: Одесса Репутация: 3 Всего: 19 |
En_t_end
В общих чертах так: создаеш класс перегружаеш << операторы для него, в которых делаеш send по длине параметра (для данных переменной длины надо добавить какойто разделитель перегружаеш >> опрераторы в которых делаеш recv пока не будет данных нужной длинны |
|||
|
||||
En_t_end |
|
||||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2074 Регистрация: 4.12.2004 Репутация: нет Всего: 20 |
Mad
В смысле ?... это что перебор получается ? ![]() Добавлено @ 18:17
В том-то и проблема, что я не знаю какие данные должны прийти. Вернее я то знаю, обьект класса не знает. Есть мысля по этому поводу...
То есть так можно будет скрыть от программиста цикл приема данных по частям. |
||||||
|
|||||||
Mad |
|
||||
Опытный ![]() ![]() Профиль Группа: Эксперт Сообщений: 656 Регистрация: 18.10.2004 Где: Одесса Репутация: 3 Всего: 19 |
нет, например
также и для других типов данных(только надо еще добавить проверку саколько принято ![]() |
||||
|
|||||
En_t_end |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2074 Регистрация: 4.12.2004 Репутация: нет Всего: 20 |
Mad
Есть ещё проблема с размерами сетевых пакетов для протокола TCP/IP. Нужно каким-то образом точно разбить данные(скорее всего придется узнавать максимально возможный размер пакета, кстати как это можно сделать, как можно переносимей для винды) и отправить их по средством << настолько чисто, так чтобы для программиста, пользующегося обьектом, все это выглядело в одной операции. |
|||
|
||||
Mad |
|
||||||
Опытный ![]() ![]() Профиль Группа: Эксперт Сообщений: 656 Регистрация: 18.10.2004 Где: Одесса Репутация: 3 Всего: 19 |
Если в приведенном мной коде добавить контроль поступления
тогда у тебя оператор выйдет только после получения 4 байтов (т.е полно int как и нужно было ![]()
а зачем ? TCP и так дает полный поток. Если в самом операторе ждать получения полных данных, то уже без разницы как там TCP этиданный разбила (тем более, что они могут быть дополнительно разбиты при пересылке роутером) |
||||||
|
|||||||
En_t_end |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2074 Регистрация: 4.12.2004 Репутация: нет Всего: 20 |
Mad
ОК... спасибо... будем работать Добавлено @ 18:38
Просто я сам был свидетелем работы одной программы сделанной для отмазки. Там наблюдался глюк с приемом и отправкой большого обьема данных. Получалось, что данные приходили либо не полностью, либо вовсе не приходили. Мое беспокойство было вызванно именно по поводу отправки... система сама разбивает данные ? ЗЫ просто сам я кроме больше чем 100 байт через TCP/IP не передовал. |
|||
|
||||
bel_nikita |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Эксперт Сообщений: 2304 Регистрация: 12.10.2003 Где: Поезд №21/22 ( ст . Прага ) Репутация: 1 Всего: 47 |
En_t_end
Что-то подобное реализовывал 2 года назад. Можно сделать, что данные в буфер кладутся в течении 50 мсек, а потом отсылаются. И так же контроль буфера, т.е. если буфер полон - данные отсылаются. Также можно ввести идентификаторы:
|
|||
|
||||
Mad |
|
||||
Опытный ![]() ![]() Профиль Группа: Эксперт Сообщений: 656 Регистрация: 18.10.2004 Где: Одесса Репутация: 3 Всего: 19 |
При отправке (вызове send) возвращаеться сколько данных помещенно в буффер, с контролем получаеться так
так я максимум до 20Мб пересылал |
||||
|
|||||
En_t_end |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2074 Регистрация: 4.12.2004 Репутация: нет Всего: 20 |
Mad
Thks! bel_nikita Очень интересное предложение, попробую реализовать. |
|||
|
||||
En_t_end |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2074 Регистрация: 4.12.2004 Репутация: нет Всего: 20 |
bel_nikita
Насколько я понимаю, если расширить ваш совет, то можно будет добиться следующей абстракции:
|
|||
|
||||
Mad |
|
|||
Опытный ![]() ![]() Профиль Группа: Эксперт Сообщений: 656 Регистрация: 18.10.2004 Где: Одесса Репутация: 3 Всего: 19 |
Это уже зависит от того, какие именно данные ты собираешся пересылать например, если у тебя по сокету идут только структуры фиксированной велечины, и в строгом порядке, то пересылка их размера просто увеличит обьем генерируемого трафика, ез какойто выгоды а вот если ты будеш пересылать бинарные данные различной длины (напримерjpeg файлы ![]() TCP предоставляет только транспорт, протокол обменна клиент<->сервер(протокол высокого уровня) надо разрабатывать самому |
|||
|
||||
bel_nikita |
|
||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Эксперт Сообщений: 2304 Регистрация: 12.10.2003 Где: Поезд №21/22 ( ст . Прага ) Репутация: 1 Всего: 47 |
En_t_end
Да, именно так.
Хотя это уже разновидности реализации на усмотрение разработчика. Вообще, хорошо бы разбить все на уровни: транспортный, пакетный и пользовательский. Транспортный(физический) только непостредственно прием/передача. Пакетный - создание пакетов для отсылки или распаковка при приеме. Пользовательский или сервисный уровень - это и есть перегрузка операторов << >>. Так же хорошо(как и говорил выше) сделать отдельный тред на отсылку, или другими словами таймер. Как только первая порция(назавем так) данных поступипа - включается таймер и данные кладуться в буфер. Как только прошло допустим 50 мсек или в буфере нет уже места - данные отсылаются. Ну и конечно, предусмотреть идентификатор FLUSH - отсылка/очистка буфера, т.е. данные сразу отсылаются без таймера. Ну и конечно, нужно знать для чего это все нужно? Если это файлы, то тут лучше использовать FTP. Если какие-то большие объемы информации, то обязательно нужно реализовывать пакетный уровень. Ведь в TCP первый высланный пакет может прийти последним ![]() |
||||
|
|||||
En_t_end |
|
||||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2074 Регистрация: 4.12.2004 Репутация: нет Всего: 20 |
bel_nikita
То есть надеется на последовательное заполнение буфера в цикле recv не стоит ? Добавлено @ 11:10 Пока делаю так... Создал класс родитель LSocket:
И два потомка:
Теперь реализую в потомке Accept сокет переводящийся в режим ожидания подключения. А для Join - организацую подключения со стороны клиента. Подумываю организовать специальный протокол обмена. То есть обеспечить автоматическое выделение канала FTP для передачи файлов, если будет получен соотвествующий запрос по TCP. |
||||||
|
|||||||
Mad |
|
|||
Опытный ![]() ![]() Профиль Группа: Эксперт Сообщений: 656 Регистрация: 18.10.2004 Где: Одесса Репутация: 3 Всего: 19 |
![]() ![]() ![]() ![]() ![]() ![]() |
|||
|
||||
En_t_end |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2074 Регистрация: 4.12.2004 Репутация: нет Всего: 20 |
Mad
Опять начинается ? ![]() Было же уже обсуждение этого вопроса ![]() |
|||
|
||||
Mad |
|
|||
Опытный ![]() ![]() Профиль Группа: Эксперт Сообщений: 656 Регистрация: 18.10.2004 Где: Одесса Репутация: 3 Всего: 19 |
En_t_end
скинь сылку посмотреть |
|||
|
||||
En_t_end |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2074 Регистрация: 4.12.2004 Репутация: нет Всего: 20 |
||||
|
||||
bel_nikita |
|
||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Эксперт Сообщений: 2304 Регистрация: 12.10.2003 Где: Поезд №21/22 ( ст . Прага ) Репутация: 1 Всего: 47 |
Mad
качаем и читаем: Йон Снейдер - Эффективное программирование TCP/IP |
||||
|
|||||
Mad |
|
||||||
Опытный ![]() ![]() Профиль Группа: Эксперт Сообщений: 656 Регистрация: 18.10.2004 Где: Одесса Репутация: 3 Всего: 19 |
bel_nikita
И как по твоему эти две фразы стыкуютья ? ![]()
Это верно, поэтому я и привел примеры методов чтения нужного кол-ва байтов с ожиданием полного получения, но это не изменения порядка следования Поясню отправляем буффер (1,2,3,4,5,6} при получении, могут быть такие варианты: {1,2,3,4,5,6} {1,2}{3,4,5}{6} {1,2,3,4}{5,6} и т.д но никогда не будет {1,2}{6}{3,4,5} или подобного Это сообщение отредактировал(а) Mad - 17.10.2005, 14:16 |
||||||
|
|||||||
bel_nikita |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Эксперт Сообщений: 2304 Регистрация: 12.10.2003 Где: Поезд №21/22 ( ст . Прага ) Репутация: 1 Всего: 47 |
Mad
![]() Ну, лопухнулся немного ![]() ![]() ![]() |
|||
|
||||
Mad |
|
||||
Опытный ![]() ![]() Профиль Группа: Эксперт Сообщений: 656 Регистрация: 18.10.2004 Где: Одесса Репутация: 3 Всего: 19 |
ты пытаешся послать SizeMess байт ![]() для такого протокола код будет такой :
|
||||
|
|||||
En_t_end |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2074 Регистрация: 4.12.2004 Репутация: нет Всего: 20 |
Mad
А.... теперь понятно, то есть здесь надо учитывать, что раз SizeMess - u_long - значит надо и послать размер сообщения размером с sizeof u_long. А я пытался преобразовывать размер к char*, а затем уже отсылать размер, опять же ошибочно забывая о том, что каждый символ - не есть один байт. |
|||
|
||||
Mad |
|
|||
Опытный ![]() ![]() Профиль Группа: Эксперт Сообщений: 656 Регистрация: 18.10.2004 Где: Одесса Репутация: 3 Всего: 19 |
Несовсем так, если ты посмотриш мой код, то увидиш 1. u_long парасылаеться как 4 байта в бинарном виде (нет смысла приобразовавыть его в текст) 2. по приему его клиент выделяет буффер по данные, с укзанным (в занчении u_long) размером 3. идет непосредственно пересылка данных. в данном слечае совсем не важно что именно ты пересылаеш, текст или бинарные данные кстати, в случае с текстом, можно упростить алгоритм: отправитель - отсылает текстовый буфер вместе с завернающим 0x0 байтом получатель - читает поток побайтно, пока не встретит байт 0x0 ![]() |
|||
|
||||
En_t_end |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2074 Регистрация: 4.12.2004 Репутация: нет Всего: 20 |
Mad
Я как не пробывал, не хочет отсылаться этот конечный байт ![]() ЗЫ спасибо! Вопросы у меня ещё есть, как сформулирую их получше - выложу. Добавлено @ 10:37 Хотя нет... все таки можно и нужно отправлять нуль-терминатор. Просто нужно отправлять (lstrlen(message)+1)*sizeof(char) - столько байт |
|||
|
||||
![]() ![]() ![]() |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | C/C++: Сети | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |