| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > C/C++: Сети > Концепция любого класса для работы с winsock |
| Автор: En_t_end 15.10.2005, 17:55 | ||
| Занимаюсь разработкой класса инкапсулирующего возможности winsocket'ов. Нужно добиться подобной абстракции: Псевдокод:
Где >> и << операторы отправки и примема данных соотвественно. То есть мне надо достичь потоковой гибкости и простоты. Просто мысли разбегаются... вообще как примерно должен выглядеть такой класс ? Если можно, то в общих чертах. |
| Автор: Mad 15.10.2005, 18:05 |
| En_t_end В общих чертах так: создаеш класс перегружаеш << операторы для него, в которых делаеш send по длине параметра (для данных переменной длины надо добавить какойто разделитель перегружаеш >> опрераторы в которых делаеш recv пока не будет данных нужной длинны |
| Автор: En_t_end 15.10.2005, 18:14 | ||||||
Mad
В смысле ?... это что перебор получается ? Добавлено @ 18:17
В том-то и проблема, что я не знаю какие данные должны прийти. Вернее я то знаю, обьект класса не знает. Есть мысля по этому поводу...
То есть так можно будет скрыть от программиста цикл приема данных по частям. |
| Автор: Mad 15.10.2005, 18:20 | ||||
нет, например
также и для других типов данных(только надо еще добавить проверку саколько принято |
| Автор: En_t_end 15.10.2005, 18:22 |
| Mad Есть ещё проблема с размерами сетевых пакетов для протокола TCP/IP. Нужно каким-то образом точно разбить данные(скорее всего придется узнавать максимально возможный размер пакета, кстати как это можно сделать, как можно переносимей для винды) и отправить их по средством << настолько чисто, так чтобы для программиста, пользующегося обьектом, все это выглядело в одной операции. |
| Автор: Mad 15.10.2005, 18:30 | ||||||
Если в приведенном мной коде добавить контроль поступления
тогда у тебя оператор выйдет только после получения 4 байтов (т.е полно int как и нужно было
а зачем ? TCP и так дает полный поток. Если в самом операторе ждать получения полных данных, то уже без разницы как там TCP этиданный разбила (тем более, что они могут быть дополнительно разбиты при пересылке роутером) |
| Автор: En_t_end 15.10.2005, 18:33 | ||
| Mad ОК... спасибо... будем работать Добавлено @ 18:38
Просто я сам был свидетелем работы одной программы сделанной для отмазки. Там наблюдался глюк с приемом и отправкой большого обьема данных. Получалось, что данные приходили либо не полностью, либо вовсе не приходили. Мое беспокойство было вызванно именно по поводу отправки... система сама разбивает данные ? ЗЫ просто сам я кроме больше чем 100 байт через TCP/IP не передовал. |
| Автор: bel_nikita 15.10.2005, 18:42 | ||
| En_t_end Что-то подобное реализовывал 2 года назад. Можно сделать, что данные в буфер кладутся в течении 50 мсек, а потом отсылаются. И так же контроль буфера, т.е. если буфер полон - данные отсылаются. Также можно ввести идентификаторы:
|
| Автор: Mad 15.10.2005, 18:52 | ||||
При отправке (вызове send) возвращаеться сколько данных помещенно в буффер, с контролем получаеться так
так я максимум до 20Мб пересылал |
| Автор: En_t_end 16.10.2005, 08:33 |
| Mad Thks! bel_nikita Очень интересное предложение, попробую реализовать. |
| Автор: En_t_end 16.10.2005, 08:44 | ||
| bel_nikita Насколько я понимаю, если расширить ваш совет, то можно будет добиться следующей абстракции:
|
| Автор: Mad 16.10.2005, 12:16 | ||
Это уже зависит от того, какие именно данные ты собираешся пересылать например, если у тебя по сокету идут только структуры фиксированной велечины, и в строгом порядке, то пересылка их размера просто увеличит обьем генерируемого трафика, ез какойто выгоды а вот если ты будеш пересылать бинарные данные различной длины (напримерjpeg файлы TCP предоставляет только транспорт, протокол обменна клиент<->сервер(протокол высокого уровня) надо разрабатывать самому |
| Автор: bel_nikita 16.10.2005, 18:56 | ||||
En_t_end
Да, именно так.
Хотя это уже разновидности реализации на усмотрение разработчика. Вообще, хорошо бы разбить все на уровни: транспортный, пакетный и пользовательский. Транспортный(физический) только непостредственно прием/передача. Пакетный - создание пакетов для отсылки или распаковка при приеме. Пользовательский или сервисный уровень - это и есть перегрузка операторов << >>. Так же хорошо(как и говорил выше) сделать отдельный тред на отсылку, или другими словами таймер. Как только первая порция(назавем так) данных поступипа - включается таймер и данные кладуться в буфер. Как только прошло допустим 50 мсек или в буфере нет уже места - данные отсылаются. Ну и конечно, предусмотреть идентификатор FLUSH - отсылка/очистка буфера, т.е. данные сразу отсылаются без таймера. Ну и конечно, нужно знать для чего это все нужно? Если это файлы, то тут лучше использовать FTP. Если какие-то большие объемы информации, то обязательно нужно реализовывать пакетный уровень. Ведь в TCP первый высланный пакет может прийти последним |
| Автор: En_t_end 17.10.2005, 11:01 | ||||||
bel_nikita
То есть надеется на последовательное заполнение буфера в цикле recv не стоит ? Добавлено @ 11:10 Пока делаю так... Создал класс родитель LSocket:
И два потомка:
Теперь реализую в потомке Accept сокет переводящийся в режим ожидания подключения. А для Join - организацую подключения со стороны клиента. Подумываю организовать специальный протокол обмена. То есть обеспечить автоматическое выделение канала FTP для передачи файлов, если будет получен соотвествующий запрос по TCP. |
| Автор: Mad 17.10.2005, 12:58 | ||
|
| Автор: En_t_end 17.10.2005, 13:39 | ||
Mad
Опять начинается ? Было же уже обсуждение этого вопроса |
| Автор: Mad 17.10.2005, 13:43 | ||
En_t_end
скинь сылку посмотреть |
| Автор: En_t_end 17.10.2005, 13:52 |
| http://forum.vingrad.ru/index.php?showtopic=57342 |
| Автор: bel_nikita 17.10.2005, 14:03 | ||||
Mad
http://files.rsdn.ru/20918/tcpip.zip |
| Автор: Mad 17.10.2005, 14:14 | ||||||
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} или подобного |
| Автор: bel_nikita 17.10.2005, 14:52 | ||
Mad
Ну, лопухнулся немного |
| Автор: Mad 21.10.2005, 14:06 | ||||
ты пытаешся послать SizeMess байт для такого протокола код будет такой :
|
| Автор: En_t_end 21.10.2005, 14:14 | ||
Mad
А.... теперь понятно, то есть здесь надо учитывать, что раз SizeMess - u_long - значит надо и послать размер сообщения размером с sizeof u_long. А я пытался преобразовывать размер к char*, а затем уже отсылать размер, опять же ошибочно забывая о том, что каждый символ - не есть один байт. |
| Автор: Mad 21.10.2005, 14:32 | ||
Несовсем так, если ты посмотриш мой код, то увидиш 1. u_long парасылаеться как 4 байта в бинарном виде (нет смысла приобразовавыть его в текст) 2. по приему его клиент выделяет буффер по данные, с укзанным (в занчении u_long) размером 3. идет непосредственно пересылка данных. в данном слечае совсем не важно что именно ты пересылаеш, текст или бинарные данные кстати, в случае с текстом, можно упростить алгоритм: отправитель - отсылает текстовый буфер вместе с завернающим 0x0 байтом получатель - читает поток побайтно, пока не встретит байт 0x0 |
| Автор: En_t_end 22.10.2005, 10:30 | ||
Mad
Я как не пробывал, не хочет отсылаться этот конечный байт ЗЫ спасибо! Вопросы у меня ещё есть, как сформулирую их получше - выложу. Добавлено @ 10:37 Хотя нет... все таки можно и нужно отправлять нуль-терминатор. Просто нужно отправлять (lstrlen(message)+1)*sizeof(char) - столько байт |