Как сейчас модно программировать сетевые приложения на С++?

yolki

или всё не так далеко ушло и на плюсах используют socket/bind/listen/etc ?
в купе с FD_* макросами?

psihodog

сейчас не модно на плюсах

Marinavo_0507

Почитай FAQ. Посмотри на библиотеку ACE.

poi1981

читай C++ Network Programming: Mastering Complexity with ACE and Patterns

Landstreicher

Я бы посоветовал 100 раз подумать, перед тем как начинать писать сетевое приложение на C++.

Codcod

А что там сложного то?

Landstreicher

Во-первых, писать утомительно (однообразный, рутинный код).
Во-вторых, страшный и долгий геморрой при отладке.

yolki

ок, а на чём сейчас модно писать сетевые приложения?
простенький сервер, обрабатывающий 5-10 типовых запросов.
запросы-ответы текстовые.
можно было конечно и на каких-нибудь скриптах и под apache, только это толсто всё.
хочется, чтобы вещь в себе занимала не больше 200-300кб (примерно).
скажем так - на Delphi под винду с использованием Indy это пишется в несколько десятков строк.
Но нужно под юниксы. Ок, а в "С" придумали что-нибудь более высокоуровневое?
// Последний раз кодил сокеты под юниксом курсе на втором ММ, а было это ... 9 лет назад

durka82

Мб тебе поможет QT(кросплатформенная либа для плюсов).
Правда я точно не знаю, что входит в бесплатную версию...

yolki

Я что-то думал, что QT - в основном визуальные компоненты: кнопочки, скроллбары, чекбоксы...
Что там есть сетевого?

kokoc88

Не знаю, но по-моему чтобы написать поставленную задачу, требуется настолько базовая функциональность от сокетов, что можно красиво руками написать за пару часов на socket API.

durka82

А я думал, что QT не отчичается от любой другой библиотеки высокоуровневой разработки типа библиотек Java/.net (в смысле предоставляемой функциональности).
Подробности не знаю

Landstreicher

> ок, а на чём сейчас модно писать сетевые приложения?
> простенький сервер, обрабатывающий 5-10 типовых запросов.
> запросы-ответы текстовые.
Однозначно скриптовые языки в духе Perl, Python, Tcl, Lua итп.
У меня есть очень положительный опыт написания подобных вещей на Python, поэтому я бы порекомендовал его.
> можно было конечно и на каких-нибудь скриптах и под apache, только это толсто всё.
> хочется, чтобы вещь в себе занимала не больше 200-300кб (примерно).
Не совсем понял. Чтобы жрало не более 200 кб памяти при работе?
> скажем так - на Delphi под винду с использованием Indy это пишется в несколько десятков строк.
С помощью Python это пишется за пару десятков строк. См. twisted.

yolki

200-300кб = сурцы + исполняемая часть, без разделяемых библиотек в случае С/С++
20-30кб в случае скриптового языка.

ppplva

А почему такие жесткие требования к скриптовым языкам ?

sergey_m

Может вообще написать его под inetd и не париться? Тогда приложение практически перестанет быть сетевым

Realist

QT содержит сетевые компоненты. С Qt4 библиотека разделена так, что можно писать не оконные приложения с этой библиотекой (все же она для написания интерфейсов в первую очередь). Qt — толстая библиотека.
На плюсах много разных библиотек типа Socket++, всякие опен-суррс проекты для создания удобного интерфейса и написания сетевых приложений.
Можно руками написать работу с сетью, причем довольно переносимо. Могу пример прислать.
На самом деле +1 за python и тому подобное.

yolki

ок, буду думать.
питон не знаю. перл только нюхал

Werdna

Может вообще написать его под inetd и не париться?

по форку на запрос? ну-ну...
я бы рекомендовал взять готовый tcp-сервер, поддерживающий модули. Если интересует такой — могу дать, но он только под freebsd, ибо юзает kqueue. зато поддерживает модули, всё так динамично и грамотно, даже из под рута не пускается, ругается.
Ещё могу дать свой, он работает и под линуксом на RTSIG, но жутко заточен под http, т. е. из него сделать что-то другое — надо покрамсать много кода.
А вообще, если писать сетевой сервер, то надо под BSD. такая штука эта kqueue клёвая, а линуксовые сигналы как оказалось сосут — при высокой нагрузке будут сегфолты непонятно откуда. :/

ppplva

линуксовые сигналы как оказалось сосут — при высокой нагрузке будут сегфолты непонятно откуда
Ты точно в той программе iconv не используешь ? Из-за него, , тоже сегфолты бывают

Ivan8209

> по форку на запрос? ну-ну..
И что?
---
"Machine cycles are cheap..."

Landstreicher

> а линуксовые сигналы как оказалось сосут — при высокой нагрузке будут сегфолты непонятно откуда. :/
учитывая , думаю дело не в ядре

sergey_m

по форку на запрос?
Автор треда не говорил, что необходимо выдерживать n тысяч запросов в секунду. Может ему этого и не надо, тогда писать под inetd самое оно.

VitMix

Я бы посоветовал 100 раз подумать, перед тем как начинать писать сетевое приложение на C++.
А что там сложного то?
А кто говорил, что это сложно? Речь не о том, что это сложно, а о том, что не стоит этого делать без уважительных причин. И на первом месте тут не сложность, а скорее требования к безопасности, предъявляемые к сетевым приложениям.

Olyalyau

Во-первых, писать утомительно (однообразный, рутинный код).
Только и занимаюсь, что сетевыми приложениями на C и C++. Нормальный код, не утомляет.
Во-вторых, страшный и долгий геморрой при отладке.

Геморрой при отладке прямо пропорционален кривизне рук и от других факторов зависит слабо.

Olyalyau

Проблема с сетевыми (и не только, любыми требующими работы с ОС, а не только с STL) на C++ только в том, что пишешь скорее всего под Posix или под какую-нибудь нестандартную OC вроде окончатых DOS-потомков. Так как ни POSIX, ни одна из этих OC не является по-настоящему объектно-ориентированной (в системные вызовы объекты не передаются то где-нибудь у тебя или в библиотеке, которую используешь, будет переход от объектного кода к функциональному. А так как работает это всё в комплексе, ты получаешь в своей программе отрицательные стороны и того и другого подхода. Более того, граница между функциональным и объектным кодом не чёткая, не локализованная в одном месте, и в итоге артефакты функционального кода (да и вообще, артефакты парадигмы ОС) у тебя вылезают откуда только можно и пролезают даже на самый верхний уровень твоего объектного кода.
За примерами далеко ходить не надо: в POSIX парадигма строк — 0-терминированные последовательности октетов. В С++ парадигма строк — std::string. Так вот, артефакты парадигмы POSIX вылезают в STL в виде необходимости передавать конструкторам файловых потоков имя файла как 0-терминированную последовательность октетов, а вовсе не std::string, и уж тем более не юникодные строки.
Работаешь со временем — обломись, нет в STD C++ ничего на эту тему. А значит, либо обращаешься к POSIX-функциям, тяготеющим к C, либо к нестандартным библиотекам, предоставляющим обёртки к тем же функциям. И вот такой хлам прёт изо всех щелей.
Шобы было счастье, хорошо бы пользовать ровно одну парадигму. Снизу доверху. Но пока что для C++-парадигмы реальной возможности это делать нет (существующие полностью объектно-ориентированные ОС практически нигде не применяются).
А использовать С-парадигму не катит, потому как она есть тёмное прошлое, в котором нет даже принципа "выделение ресурса есть инициализация". А без этого принципа, ресурсы имеют дурную привычку утекать. Живой пример — Oracl'овый OCI. Как он течёт памятью, это песня!

Olyalyau

Посмотри на библиотеку ACE.

ACE использовать не советую. Большая библиотека, а значит с кучей багов.
Если нужны обёртки вокруг сокетов, мутексов, потоков и т.д., проще (чем разбираться в чужих интерфейсах) и надёжнее (потому что проще отладить) написать свои.

evgen5555



Шобы было счастье, хорошо бы пользовать ровно одну парадигму.

Развелось, бл%, теоретиков...

yolki

Вот именно поэтому хотел узнать, может в юниксах есть приличные ОО-обёртки над сокетами..

Werdna

Так вот, артефакты парадигмы POSIX вылезают в STL в виде необходимости передавать конструкторам файловых потоков имя файла как 0-терминированную последовательность октетов, а вовсе не std::string, и уж тем более не юникодные строки.

Существуют в природе дибилы, в экспортных функциях их библиотек принимаются параметры в виде STL-контейнеров. Что КАТЕГОРИЧЕСКИ делать нельзя.
Юникодовые строки окейно жуются функциями их понимающими. При чем тут STL — не понял.
Работаешь со временем — обломись, нет в STD C++ ничего на эту тему

А с какой стати в stl что-либо должно быть для ВРЕМЕНИ? Это ведь такая скользкая вещь, к тому же платформозависимая!
Шобы было счастье, хорошо бы пользовать ровно одну парадигму.

Не надо стремиться к вселенскому счастью. Не надо писать классы сокетов и классы таймеров. Ибо это изврат полный, абстракция на пустом месте ради непонятно чего.

sergey_m

Если нужны обёртки вокруг сокетов, мутексов, потоков и т.д.
Кстати вот прикольная обёртка, но она не плюсовая.
http://www.dellroad.org/pdel

amkharchenko

Правильно. Настоящие пацаны используют исключительно klibc. А реальные пацаны --- пишут свою libc.

Ivan8209

Не просто из любопытства, ты не встречал легковесных TCP/IP стеков?
---
...Я работаю антинаучным аферистом...

sergey_m

Не просто из любопытства, ты не встречал легковесных TCP/IP стеков?
google://"light weight TCP stack"

Ivan8209

Так я умею.
Может, ты встречал что-то полезное, видел обзоры, мнения и т.п.
---
...Я работаю антинаучным аферистом...

sergey_m

Видел мнение, что первая ссылка - хороший софт.

Ivan8209

lwIP?
Ладно.
---
...Я работаю антинаучным аферистом...

Olyalyau

Существуют в природе дибилы, в экспортных функциях их библиотек принимаются параметры в виде STL-контейнеров. Что КАТЕГОРИЧЕСКИ делать нельзя.

Объясни свою мысль, в случае если контейнеры передаются по ссылке или парой итераторов. Почему этого категорически нельзя делать?
Юникодовые строки окейно жуются функциями их понимающими. При чем тут STL — не понял.

Юникодовые строки плохо жуются программами под POSIX. У меня — то терминал (с поддержкой UTF8) пытается единый символ на байты разбить при переносе на новую строку, то какой-то (может старый) vim с нарезки слетает и длину строки начинает в байтах воспринимать (курсор отображает не в том месте).
И кстати, моё возмущение, в основном, вызывают не Юникодные строки, а нуль-терминированные. По двум причинам.
1. В них нельзя иметь внутренние нули. Ни одна ни POSIX'овая ни C функция не понимает текстовых строк с нулями. Почему? ведь 0x00 — такой же символ, как и все остальные. В результате бинарные данные нельзя интерпретировать как строки. Это приводит к проблеме из реальной жизни: мне нужно делать регулярный поиск (с регулярным выражением, генерируемым по пользовательскому вводу) по бинарным UDP пакетам. Пользователь вводит extended POSIX regular expression (eregexp я по нему легко могу сгенерировать то выражение, которое надо искать. Но. В eregexp нет возможности указать символ 0x00, да и вообще какой-либо символ его кодом. И стандартная POSIX'овая функция regexec не умеет искать по бинарным данным — а умеет только по нуль-терминированной строке. В результате я не могу ей воспользоваться. И не только я. grep умеет искать 0x00 (ему можно задавать код любого символа в восьмеричном виде как \000); в grep'е машинка регулярных выражений своя, с нуля написанная. (Какой такой code reuse! Нам чтоб работала надо.) А тот же sed не умеет. В итоге искать можно, а для замены с 0x00 уже прогу писать надо. Хоть какую, хоть на бейсик-подобном перле, а надо.
2. Сравнения строк в случае их несовпадения, занимает неоправданно много времени, особенно в случае сравнения строк с длинными совпадающими префиксами. Если бы строки были чесными: размер+значение, то размеры бы часто не совпадали, да и для строк с заведомо длинными совпадающими префиксами, можно было бы организовать сравнение (правда только на == и !=) с конца строки. Это порождает реальную проблему. Она состоит в медленном разрешении С++ символов из шареных либ. Разрешение происходит во время выполнения, символов много, много символов с совпадающими префиксами: из-за механизма манглинга, который из namespas'ов, вложенных пространств имён, имён классов, вложенных имёт классов порождает длинные имена для символов и длинными совдадающими префиксами (особенно для символов, относящихся к одному классу). А если там ещё классовые переменные в методы передаются, так это вообще жесть. Если интересно — запустите objdump -x или nm на шареный ELF с C++-прогой, посмотрите на длины символов. С особенным вниманием на символы которые этот ельф из шареных либ грузит (а не сам определяет, хотя для плагинов и те важны, так как тоже разрешаются во время выполнения). То, во что превращаются имена из boost'а (да из из STL, параметры шаблонов-то тоже в мангленные имена входят) — это просто песня, символы длиннее строк терминала. А ещё попробуйте шареную C++ прогу перелинковать как статическую, и поперейте прирост производительности (особенно на запуск проги, при поиске обычно используется отложенное разрешение символов с кешированием — через GOT и PLT). А всё почему — сравнение нуль-терминированных строк равенство (в случае частого неравенства) дороже чем надо, так как всегда требует сканирования, которое дорого для строк с длинными одинаковыми префиксами.
А с какой стати в stl что-либо должно быть для ВРЕМЕНИ? Это ведь такая скользкая вещь, к тому же платформозависимая!

Это в смысле сильно зависит, не в Китае ли комп собирали, а то у них там какой-то свой календарь
А если серьёзно, выделение памяти тоже платформенно зависимаю штука (ох как зависимая! вспомните, что бывает flat-память, бывает сегментированная память, бывает странично организованная память, бывает сегментно-страничная, бывают страницы разного размера на одной и той же машине в один и тот же момент времени, бывает процесная подкачка, сегментная подкачка, страничная подкачка, бывает развлекуха с near- и far- одновременно существующими указателями, бывает NUMA, и всё это бывает не в гетерогенной сети, а на одном, родимом IA-32). И ничего, есть себе простейшее семейство malloc в ANCI C, и семейство new в ISO C++, и все довольны.
Ну а календарь (за исключением китайцев и прочих особых народов ) на всех платформах одинаковый. Тем более, что в boost'е, точно помню, есть как минимум возможность работы и в Юлианском, и в Григорианском календаре.
Не надо стремиться к вселенскому счастью. Не надо писать классы сокетов и классы таймеров. Ибо это изврат полный, абстракция на пустом месте ради непонятно чего.

Кто ж спорит, что не надо. Приходится. Приходится писать классы-обёртки вокрук pthread mutex'ов и rw-lock'ов. Потому как хочется, чтобы занятые мутексы, локи, память и прочие ресурсы автоматически освобождались при выходе из блока, в котором они захвачены (с памятью ситуация несколько сложнее, её ещё требуется куда-нибудь передавать, но всё равно, хочется чтобы она автоматически освобождалась, когда больше никому не нужна). И тут проблема не только с тем, что можно забыть что-то освободить, хотя это наиболее частый трабл. Тут проблема и с безопасностью исключений.
Например, если у вас класс делает в конструкторе два new и на второй ему кидают std::bad_alloc, то без resource-guardian'а (и без честной обработке исключений вокруг каждого new, cout <<, push_back, resize и т.д., в которой надо честно освободить все занятые ресурсы, которые не передадутся наружу
у вас memory leak, с чем я вас и поздравляю.
Кому-то, а memory leak, подумаешь! А я пишу серверные приложения, которые месяцами работают без перезагрузки. И которые, не должны пухнуть-пухнуть, а потом получать жёсткий kill от ядра, когда всю память займут. И не должны тормозить сервак (он делом занимается, ни в чём не повинных пользователей обслуживает когда почти всю память займут, но ядро его ещё не грохнет. Грохнет-то ладно, перезапустится. Конечно пока будет перезапускаться, запросы потеряет, но ести сервак на минуту тормознёт, то лучше на работу не выходить, пока клиент не угомонится
А если dead-lock будет, потому что где-то мутекс или rw-lock забыли освободить, то тоже неприятно. Но с моими обёртками для них (точнее для их автоматического освобождения по выходу из области видимости переменной-обёртки dead-lock'и у меня возникали только на попытках вызвать из одного метода, блокирующего лок класса, другой, который тоже лок бло

Olyalyau


Кстати вот прикольная обёртка, но она не плюсовая.
http://www.dellroad.org/pdel

Это не обёртка, призванная контролировать освобождение ресурсов, если я всё правильно понял.

Olyalyau

Правильно. Настоящие пацаны используют исключительно klibc. А реальные пацаны --- пишут свою libc.
Это не реальные пацаны. Я написал (для удовольствия) класс, который работает почти как cout. Но вот реализован под чистую машину, без операционки, без использования BIOS. Вот он — по-пацански писал выводимые символы с их атрибутами прямо в видео память. Правда, к этому классу пришлось дописать страничный менеджер памяти, свой new (у меня свободные блоки были огранизованы в сбалансированное дерево, что обгоняло GNU'шный malloc при частом выделении блоков случайного размера, освобождении случайных блоков (среди уже выделенных) и так в цикле, выделение/освобождении; на на менее жёстких тестах превосходство моего new не было так заметно; а сделал бы на красно-чёрном дереве, небось ещё быстрее было бы свой менеджер прерываний, свой менеджер адресных пространств и задач в них, свой запуск ELF'ов, свой переключатель задач (простейший round-robin свой драйвер ATA, свой драйвер ext2, свой IPC на передаче сообщений. Чего своего не было, так это bootstrapping'а. Я решил, что "вытаскивать себя за свои шнурки" — дело мюнхаузенов и авторов GRUB'а. Так что реализовал ELF'овый мультибут. Но всё остальное — делал сам. Даже выяснял доступную память сам, безо всяких BIOS'ов и GRUB'ов. Чисто по-пацански. Записал-прочитал-проверил-записал другое в то же место-прочитал-проверил — обе проверки прошли: тута есть память, пошли к следующему адресу. Учёл ПЗУ 64K-1M, аккуратно обошёл область, куда сам загружен (выясняется по собственному заголовку ELF'а, надо только сделать его загружаемым, что легко реализовать ld-скриптом; а можно меток понаставить на начала/концы загружаемых секций). Вота, вся память, что нашёл — вся моя, никакому BIOS'у под его резервы ни байта не отдал!

sergey_m

Да, освбождение ресурсов тут не причём.

Ivan8209

> моё возмущение, в основном, вызывают не Юникодные строки, а нуль-терминированные.
> По двум причинам.
> 1. В них нельзя иметь внутренние нули.
Из-за этого существуют разные API для одного и того же действия, например

$ man -h memmem
#include <string.h>

void *
memmem(const void *block, size_t blen, const void *pat, size_t plen);

> 2. Сравнения строк в случае их несовпадения, занимает неоправданно много времени,
> особенно в случае сравнения строк с длинными совпадающими префиксами.
> Если бы строки были честными: размер+значение, то размеры бы часто не совпадали,
3. Любое действие с выделением подстроки требует дополнительной памяти и копирования.
Пример

$ man 3 dirname
DIRNAME(3) NetBSD Library Functions Manual DIRNAME(3)

NAME
dirname -- report the parent directory name of a file pathname

LIBRARY
Standard C Library (libc, -lc)

SYNOPSIS
#include <libgen.h>

char *
dirname(char *path);

DESCRIPTION
The dirname function takes a pointer to a character string that con-
tains a pathname, path, and returns a pointer to a string that is a path-
name of the parent directory of path. Trailing `/' characters in path
are not counted as part of the path.

If path does not contain a `/', then dirname returns a pointer to the
string ``.''.

If path is a null pointer or points to an empty string, dirname returns
a pointer to the string ``.''.

RETURN VALUES
The dirname function returns a pointer to a string that is the parent
directory of path.

SEE ALSO
dirname(1 basename(3)

STANDARDS
o X/Open Portability Guide Issue 4, Version 2 (``XPG4.2'')
o IEEE Std 1003.1-2001 (``POSIX.1'')

BUGS
If the length of the result is longer than PATH_MAX bytes (including the
terminating nul the result will be truncated.

The dirname function returns a pointer to static storage that may be
overwritten by subsequent calls to dirname. This is not strictly a
bug; it is explicitly allowed by IEEE Std 1003.1-2001 (``POSIX.1'').

NetBSD 3.0 October 16, 2002 NetBSD 3.0

Если представлять строки как в _хороших_ языках, парой "указатель --- длина", то:
а) выделение памяти динамическое (FreeBSD 5) или статическое (выше)
почти исключается, оставляется только для исключительных случаев,
когда строка _на_самом_деле_ пересоздаётся;
б) устраняется сама возможность недочётов наподобие
усечения вылезающей за установленные рамки строки,
как это описано в "BUGS" выше.
4. Другие последствия.
Обратите внимание, что источник части неприятностей даже явно разрешён стандартом.
То есть, мало того, что стандарт устанавливает представление строк с нулевым концом,
так ещё и явно разрешает использование статических буферов.
На самом деле, SUS (ver. 2) вдобавок разрешает изменение исходной строки,
то есть dirname _может_ никак не выделять память, ни статически, ни динамически.
Зато она может _перезаписывать_ входную строку.
То есть, от программиста попросту требуется (если он пишет переносимо)
_всё_равно_ выделять память и копировать строку,
независимо от того, как поступает системная dirname,
потому что нет общедоступного способа узнать это.
О каком повторном использовании кода может идти речь,
если стандарт явным образом препятствует такому использованию,
заставляя работать заведомо неэффективным способом?
У меня нет доступа к соответствующему документу от IEEE,
но я не думаю, что там дела обстоят хоть немного лучше.
После всего вышеозначенного, о каком авторитете SUS или POSIX может идти речь?
> Пробовал переопределять malloc/realloc/valloc/delete
Кстати, вопрос.
Почему нет доступной функции, отдающей размер куска, созданного malloc?
Из-за этой мелочи, его приходится хранить отдельно.
---
...Я работаю антинаучным аферистом...

Werdna

Объясни свою мысль, в случае если контейнеры передаются по ссылке или парой итераторов. Почему этого категорически нельзя делать?

Если либа и программа её использующая используют разные реализации STL, то наступит пиздец. Элементарно, даже std::string может устроить фигню, например с аллокатором проблем не оберешься. Вообще, читай книжки, везде сказано что нельзя. И точка.
В результате бинарные данные нельзя интерпретировать как строки.

И слава Богу.
Это приводит к проблеме из реальной жизни: мне нужно делать регулярный поиск (с регулярным выражением, генерируемым по пользовательскому вводу) по бинарным UDP пакетам.

посмотри исходники grep/egrep.

sergey_m

Это приводит к проблеме из реальной жизни: мне нужно делать регулярный поиск (с регулярным выражением, генерируемым по пользовательскому вводу) по бинарным UDP пакетам.
В СОРМе работаешь?

Olyalyau

Из-за этого существуют разные API для одного и того же действия, например

Для сравнения по регулярному выражению нет API работающего для строк с нулевыми символами в середине. Если бы для всех задач было бы два API — не вопрос, я бы не возмущался.
3. Любое действие с выделением подстроки требует дополнительной памяти и копирования.

На самом деле, в схеме строка+размер тоже будет дополнительное выделение памяти при создании подстроки — как минимум для размера. Но не только. В многопоточном приложении и даже в однопоточном, если либо строка, либо подстрока не является константной, потребуется копирование и данных строки. Иначе модификация одной из этих строк может привести к модификации в другой, или даже к недействительности другой строки в случае необходимости перераспределения памяти для этой модификации.

Кстати, вопрос.
Почему нет доступной функции, отдающей размер куска, созданного malloc?
Из-за этой мелочи, его приходится хранить отдельно.

Потому что плохо думали, когда стандарты писали.

Olyalyau

Если либа и программа её использующая используют разные реализации STL, то наступит пиздец. Элементарно, даже std::string может устроить фигню, например с аллокатором проблем не оберешься. Вообще, читай книжки, везде сказано что нельзя. И точка.

Аргумент понятен. Но это относится к любой линковке объектов, скомпилированных разными компиляторами или линкованных с разными либами, имеющими один и тот же интерфейс. Меня больше интересует почему это нельзя в случае, когда все компоненты собираются на одной платформе одними и теми же средами компиляции под один и тот же ABI и с одними и теми же либами. Это наиболее частая для меня ситуация.
И слава Богу.

Аргумент не ясен. Обоснуйте связь Яхве и нуль-терминированных строк.
посмотри исходники grep/egrep.

Предложение достойное истинного гуру. Мне не надо смотреть. Мне надо, чтобы у меня работало. С наименьшим геморроем разработки и поддержки. Для этого мне нужна стандартная функция, в стандартной либе.
Взять код grep я не могу по лицензионным соображениям — придётся брать GNU grep, а лицензировать свою программу по GPL/LGPL я не могу, так как не определяю лицензионную политику работодателя. А чтобы машинку регулярных выражений написать, мне не нужно заглядывать в код grep. Достаточно книжки по ним (машинкам) и время (гораздо меньшее, чем если бы пришлось разбираться в чужом коде). Проблема в том, что писать это самому не является решением с "наименьшим геморроем разработки и поддержки". На данный момент обошёлся собственным простейшим regexp-matching'ом для обхода нулей в регекспе + regexec по строке, в которой нули заменены пробелами. Такое решение меня не впечатляет, но обладает "наименьшим геморроем разработки и поддержки".

Olyalyau

В СОРМе работаешь?


Нет
А жаль...
Занимаюсь RADIUS-протоколом.

Marinavo_0507

Взять код grep я не могу по лицензионным соображениям — придётся брать GNU grep,
А в libc от BSD нет разве регулярных выражений?
Или там libpcre какую посмотреть.

sergey_m

Занимаюсь RADIUS-протоколом.
Есть специальные библиотеки, которые дают atribute/value пары. Зачем такое богохульство как: "поиск регулярного выражения в бинарных UDP пакетах"? Вообще разработчик RADIUS приложения не должен знать про UDP. Может быть в будущем RADIUS будет по SCTP работать.
А не GPL реализации RE существуют.

Olyalyau

А в libc от BSD нет разве регулярных выражений?

А libc в FreeBSD разве не GNU'шная? У меня было впечатление, что во FreeBSD нет собственной среды разработки.
Или там libpcre какую посмотреть.
Гляну.

Olyalyau

Есть специальные библиотеки, которые дают atribute/value пары. Зачем такое богохульство как: "поиск регулярного выражения в бинарных UDP пакетах"?

Я и сам RADIUS-пакеты разбираю влёт. Но это офигительно дорого. Со всеми оптимизациями, которые я сделал (и для которых использовал собственный тривиальный regexp-matching) я проигрываю в поиске grep'у в несколько раз. А дорогой поиск не годится, так как искать надо по многим мегабайтам и гигабайтам сырых RADIUS-пакетов — у крупных inet,voip,etc.-провайдеров RADIUS-статистики в сутки набирается окиян.
То есть есть тривиальный путь оптимизации — поискать просто regexp'ом по файлу с пакетами, а потом, где есть матчинг, пакет с матчингом разобрать и проверить, то ли нашли. Сейчас у меня реализован недо-вариант этой оптимизации. Сделать её полноценно я не могу из-за неполноты моих regexp-matching процедур. И, как я уже говорил, мой недо-вариант проигрывает grep'у в несколько раз.
А когда этой оптимизации не было и я честно разбирал каждый пакет — тормозило не в несколько раз, а на пару десятичных порядков, по сравнению с тем же grep'ом.
Вообще разработчик RADIUS приложения не должен знать про UDP.

Это спорная позиция. RADIUS-сервер всё-таки UDP пакеты получает. Хотя я не совсем правильно выразился — я ищу, разумеется только в содержимом пакета, а UDP заголовок операционка парсит.

sergey_m

А libc в FreeBSD разве не GNU'шная?
Ты издеваешься? Интересно, до появления GNU все сидели без libс и ждали появления GNU?

sergey_m

Я и сам RADIUS-пакеты разбираю влёт. Но это офигительно дорого. Со всеми оптимизациями, которые я сделал (и для которых использовал собственный тривиальный regexp-matching) я проигрываю в поиске grep'у в несколько раз. А дорогой поиск не годится, так как искать надо по многим мегабайтам и гигабайтам сырых RADIUS-пакетов — у крупных inet,voip,etc.-провайдеров RADIUS-статистики в сутки набирается окиян.
Не разбирая протокол RADIUS, у тупо грепя может быть и быстрее. Но в конце концов закончится невылавливаемыми багами.
А работу эту надо выполнять не раз в сутки, а круглые сутки, постоянно, по мере прихода данных. Если обработку выполнять постоянно, то можно более точно мониторить загрузку машин, выполняющих эту работу - тупо строить графики загрузки CPU, памяти, I/O. Более предсказуемо прогнозировать когда закончатся вычислительные ресурсы. Там где очень много данных, там periodic jobs не рулят.

Ivan8209

> А libc в FreeBSD разве не GNU'шная?
Нет.
Из-за этого, GNU не поддерживает некоторых полезных действий, как, например, fgetln.
> У меня было впечатление, что во FreeBSD нет собственной среды разработки.
В зависимости от того, что ты под этим понимаешь.
Если компиляторы, то да, их нет.
С другой стороны, существуют непогнутые компиляторы,
которые никто не мешает задействовать, если это требуется.
---
...Я работаю антинаучным аферистом...

Ivan8209

> Обоснуйте связь Яхве и нуль-терминированных строк.
Они даны нам господом богом.

$ sed '/^ \*\//q' /usr/src/lib/libradius/radlib.c
/* $NetBSD: radlib.c,v 1.5 2005/03/16 10:34:25 he Exp $ */

/*-
* Copyright 1998 Juniper Networks, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
$ sed '/^ \*\//q' /usr/src/lib/libc/regex/*.c
/* $NetBSD: engine.c,v 1.18 2004/04/03 17:00:00 christos Exp $ */

/*-
* Copyright (c) 1992, 1993, 1994
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Henry Spencer.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)engine.c 8.5 (Berkeley) 3/20/94
*/

---
...Я работаю антинаучным аферистом...

Ivan8209

>> 3. Любое действие с выделением подстроки требует дополнительной памяти и копирования.
> На самом деле, в схеме строка+размер тоже будет дополнительное
> выделение памяти при создании подстроки — как минимум для размера.
Это мелочь по сравнению с размером подстроки, к тому же,
оно ещё и хранится чаще на стеке, а не в куче.
> Но не только. В многопоточном приложении и даже в однопоточном,
> если либо строка, либо подстрока не является константной,
> потребуется копирование и данных строки.
> Иначе модификация одной из этих строк может привести к модификации в другой,
> или даже к недействительности другой строки в случае необходимости
> перераспределения памяти для этой модификации.
Это случаи, когда без копирования вообще не обойтись,
а если предполагается, что строка измениться не может
(один поток или заперта можно было бы обойтись без копирования,
если бы не идиотский API.
---
...Я работаю антинаучным аферистом...

Olyalyau

Не разбирая протокол RADIUS, у тупо грепя может быть и быстрее. Но в конце концов закончится невылавливаемыми багами.
Расскажи про баги, которые могут вылезти. Повторяю, алгоритм такой: бинарным регекспом найти некоторое совпадение, просмотреть файл назад в поисках magic'а записи (4 байта родом из /dev/random). Считать всю запись (в начале и в конце записи содержатся по 4 байта длины записи, обязаны совпасть). Запись содержит в том числе, RADIUS-пакет. Разобрать пакет, проверить, удовлетворяет ли он условиям поиска. Да — выдать его. Искать дальше.
А работу эту надо выполнять не раз в сутки, а круглые сутки, постоянно, по мере прихода данных. Если обработку выполнять постоянно, то можно более точно мониторить загрузку машин, выполняющих эту работу - тупо строить графики загрузки CPU, памяти, I/O. Более предсказуемо прогнозировать когда закончатся вычислительные ресурсы. Там где очень много данных, там periodic jobs не рулят.

Там нет периодических работ. Приходит запрос, обрабатывается. Кроме того, записывается на диск. (Для аккаунтинга обработка может реально осуществляться отложено, отдельным от RADIUS-сервера процессом, который читает те же файлики, куда запросы складываются. Пока что никакого поиска по пакетам нет. Но вот звонит абонент, говорит: я в интернет войти не могу. Оператор в web-интерфейсе вбивает временной диапазон поиска ("Так, когда вы последний раз пытались войти?") и условие поиска (в данном случае User-Name=логин абонента). Теперь надо быстренько найти (быстренько — люди ждут) все пакеты RADIUS-обмена и выдать оператору. Оператор смотрит на атрибуты, говорит: у вас деньги кончились, услуга не подключена, пароль не угадали и т.д. Ничего связанного с прогнозированием ресурсов по времени тут нет (есть только прогнозирование требуемых ресурсов аппаратной платформы перед внедрением).

Olyalyau

В зависимости от того, что ты под этим понимаешь.
Если компиляторы, то да, их нет.

Имел в виду компилятор, библиотеки, утилиты отладки.
С другой стороны, существуют непогнутые компиляторы,
которые никто не мешает задействовать, если это требуется.

Интересны были именно родные, FreeBSD библиотеки, так как у них лицензия заведомо подходящая.

Ivan8209

> Оператор смотрит на атрибуты, говорит: у вас деньги кончились,
> услуга не подключена, пароль не угадали и т.д.
Довольно-таки странное техническое решение,
неужели нельзя посмотреть по журналу радиуса?
---
...Я работаю антинаучным аферистом...

Olyalyau

Они даны нам господом богом.

Вовсе нет. Они даны нам Томпсоном, Керниганом и прочими "пионэрами" как сказал бы "пионэр" Бутенко.

* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.

Думаю, что не пойдёт. Хотя это надо уточнять у тех, кто лицензированием занимается.

Olyalyau


Это мелочь по сравнению с размером подстроки, к тому же,
оно ещё и хранится чаще на стеке, а не в куче.

Это сильно зависит от реализации.
Это случаи, когда без копирования вообще не обойтись,
а если предполагается, что строка измениться не может
(один поток или заперта можно было бы обойтись без копирования,
если бы не идиотский API.

Интересно какой API придумаешь ты для обхода такой ситуации (без копирования данных строки):

s1 = s2.substr (2);
s2 = "Обана, s1 изменилось ;-O";

Ivan8209

>> В зависимости от того, что ты под этим понимаешь.
>> Если компиляторы, то да, их нет.
> Имел в виду компилятор, библиотеки, утилиты отладки.
Библиотеки есть.
Что подразумевается под утилитами отладки, не знаю.
Очень многие отладочные средства родные или братские (например, из OpenBSD).
>> С другой стороны, существуют непогнутые компиляторы,
>> которые никто не мешает задействовать, если это требуется.
> Интересны были именно родные, FreeBSD библиотеки,
> так как у них лицензия заведомо подходящая.
У меня сейчас нет под рукой FreeBSD.
---
...Я работаю антинаучным аферистом...

Ivan8209

>> * 2. Redistributions in binary form must reproduce the above copyright
>> * notice, this list of conditions and the following disclaimer in the
>> * documentation and/or other materials provided with the distribution.
> Думаю, что не пойдёт. Хотя это надо уточнять у тех, кто лицензированием занимается.
Ну, не настолько сложно уточнить.
А потом, всегда можно уточнить и у авторов.
---
...Я работаю антинаучным аферистом...

Ivan8209

>> Это мелочь по сравнению с размером подстроки, к тому же,
>> оно ещё и хранится чаще на стеке, а не в куче.
> Это сильно зависит от реализации.
Ну, в общем, да, только всё равно хранить пару указатель---длина проще, чем копии строк.

>> Это случаи, когда без копирования вообще не обойтись,
>> а если предполагается, что строка измениться не может
>> (один поток или заперта можно было бы обойтись без копирования,
>> если бы не идиотский API.
> Интересно какой API придумаешь ты для обхода такой ситуации (без копирования данных строки):
Там чуть выше написано:
>> Это случаи, когда без копирования вообще не обойтись,
Так можно дойти до анекдота: "Доктор, если я делаю так,
так и так, у меня начинает болеть вот здесь..."
---
...Я работаю антинаучным аферистом...

sergey_m

Для тех, у кого нет под рукой FreeBSD есть http://www.FreeBSD.org/cgi/cvsweb.cgi

Ivan8209

Там find не пустишь.
---
"...Потому что Аллах не ведёт людей неверных."

sergey_m

А как ты лицензии будешь find определять? find вообще не нужен, подскажу: всё, что не находится в каталоге contrib идёт под лицензией BSD или еще более свободной.

Ivan8209

> идёт под лицензией BSD
Некоторые сомневаются в возможности использования того, что идёт с "advertising clause,"
и пока что только UCB отозвал это требование, а сколько ещё осталось?
Хотя по мне, так это требование не настолько сложно удовлетворить.
---
...Я работаю антинаучным аферистом...

sergey_m

Во-первых, advertising clause не должно волновать в большинстве случаев и конкретно в случае . Во-вторых, advertising clause уже практически нигде не осталось.

Ivan8209

> Во-первых, advertising clause не должно волновать в большинстве случаев и конкретно в случае .
Я не знаю соответствующих обстоятельств, но может сложиться так,
что не должно волновать и (L)GPL: судя по написанному,
у него довольно специальная задача, которая не предполагает,
что код будет широко продаваться.
> Во-вторых, advertising clause уже практически нигде не осталось.
С этим сложнее.
Объём довольно-таки сложно оценить из-за гораздо более
анархичных, чем в GNU, порядков, из-за которых
/usr/bin/true или /usr/bin/objformat может идти даже
с "advertising clause" (по крайней мере, "copyrighted"
а /bin/test быть общественным достоянием ("public domain").
Вот, кстати, пример:

$ grep -rhF 'includes software' /usr/src/usr.bin | sort | uniq
includes software developed by the University of California,
* This product includes software developed by Adam Glass.
* This product includes software developed by Christos Zoulas.
* This product includes software developed by Jochen Pohl for
* This product includes software developed by Philip A. Nelson.
* This product includes software developed by the NetBSD
* This product includes software developed by the University of
* This product includes software developed for the NetBSD Project
* This product includes software developed for the NetBSD Project by
* This product includes software developed for the
* This product includes software developed by Florian Stoehr
* This product includes software developed by the NetBSD
* This product includes software developed by the NetBSD
* This product includes software develooped for the NetBSD Project by
* This product includes software developed by Eduardo Horvath.
* This product includes software developed by Jochen Pohl for
* This product includes software developed by John Polstra.
* This product includes software developed by Terrence R. Lambert.
* This product includes software developed by Winning Strategies, Inc.
* This product includes software developed by the NetBSD
* This product includes software developed by the NetBSD Foundation.
* This product includes software developed by the University of
* This product includes software developed for the NetBSD Project
* This product includes software developed for the NetBSD Project by
* acknowledgement: ``This product includes software developed by the
# This product includes software developed by the University of
# This product includes software developed by the NetBSD
# This product includes software developed by Terrence R. Lambert.
.\" This product includes software developed by Zembu Labs, Inc.
.\" This product includes software developed by the NetBSD
.\" This product includes software developed by the University of
.\" This product includes software developed for the NetBSD Project
.\" This product includes software developed for the
.\" This product includes software developed by Florian Stoehr
.\" This product includes software developed by the NetBSD
.\" This product includes software developed by Christopher G. Demetriou.
.\" This product includes software developed by Eduardo Horvath.
.\" This product includes software developed by Jochen Pohl for
.\" This product includes software developed by Winning Strategies, Inc.
.\" This product includes software developed for the NetBSD Project by
.\" This product includes software developed by The NetBSD
// acknowledgement: ``This product includes software developed by the

Только не надо говорить, что FreeBSD не содержит того, что написали,
например, те же "Winning Strategies, Inc."
Я не думаю, что за полгода всё настолько сильно изменилось.
---
...Я работаю антинаучным аферистом...

sergey_m

В FreeBSD намного меньше advertising clause, потому что с ними умышленно боролись.

Ivan8209

Возможно, но я пока не могу этого проверить.
---
...Я работаю антинаучным аферистом...

sergey_m

Пока не можешь чего-то проверить, воздерживайся от написания новых постов.

Ivan8209

А ты бы взял, да и написал, сколько оценочно "advertising clases" в исходниках FreeBSD.
Если не знать, что ты тесно связан с ними, есть полное право утверждать,
что ты неспособен дать хоть какую-то авторитетную оценку.
---
...Тут приехал бульдозер товарища Оккамы...

sergey_m

Утверждай, мне похуй.

Olyalyau

Там чуть выше написано:
>> Это случаи, когда без копирования вообще не обойтись,
Так можно дойти до анекдота: "Доктор, если я делаю так,
так и так, у меня начинает болеть вот здесь..."

Так вопрос-то в том, как API (на C++) будет понимать, что изменения ни исходной, ни результирующей строки после операции substr не будет. Насколько я знаю C++, такое ограничение средствами языка не наложить.

Ivan8209

>> Там чуть выше написано:
>>>> Это случаи, когда без копирования вообще не обойтись,
>> Так можно дойти до анекдота: "Доктор, если я делаю так,
>> так и так, у меня начинает болеть вот здесь..."
> Так вопрос-то в том, как API (на C++) будет понимать,
> что изменения ни исходной, ни результирующей строки
> после операции substr не будет.
> Насколько я знаю C++, такое ограничение средствами языка не наложить.
А как API будет понимать, что за экраном не будет сидеть человек,
исправляющий значения переменных отладчиком?
---
...Я работаю антинаучным аферистом...
Оставить комментарий
Имя или ник:
Комментарий: