Как сейчас модно программировать сетевые приложения на С++?
сейчас не модно на плюсах
Почитай FAQ. Посмотри на библиотеку ACE.
читай C++ Network Programming: Mastering Complexity with ACE and Patterns
Я бы посоветовал 100 раз подумать, перед тем как начинать писать сетевое приложение на C++.
А что там сложного то?
Во-вторых, страшный и долгий геморрой при отладке.
простенький сервер, обрабатывающий 5-10 типовых запросов.
запросы-ответы текстовые.
можно было конечно и на каких-нибудь скриптах и под apache, только это толсто всё.
хочется, чтобы вещь в себе занимала не больше 200-300кб (примерно).
скажем так - на Delphi под винду с использованием Indy это пишется в несколько десятков строк.
Но нужно под юниксы. Ок, а в "С" придумали что-нибудь более высокоуровневое?
// Последний раз кодил сокеты под юниксом курсе на втором ММ, а было это ... 9 лет назад
Правда я точно не знаю, что входит в бесплатную версию...
Что там есть сетевого?
Не знаю, но по-моему чтобы написать поставленную задачу, требуется настолько базовая функциональность от сокетов, что можно красиво руками написать за пару часов на socket API.
Подробности не знаю
> простенький сервер, обрабатывающий 5-10 типовых запросов.
> запросы-ответы текстовые.
Однозначно скриптовые языки в духе Perl, Python, Tcl, Lua итп.
У меня есть очень положительный опыт написания подобных вещей на Python, поэтому я бы порекомендовал его.
> можно было конечно и на каких-нибудь скриптах и под apache, только это толсто всё.
> хочется, чтобы вещь в себе занимала не больше 200-300кб (примерно).
Не совсем понял. Чтобы жрало не более 200 кб памяти при работе?
> скажем так - на Delphi под винду с использованием Indy это пишется в несколько десятков строк.
С помощью Python это пишется за пару десятков строк. См. twisted.
20-30кб в случае скриптового языка.
А почему такие жесткие требования к скриптовым языкам ?
Может вообще написать его под inetd и не париться? Тогда приложение практически перестанет быть сетевым
На плюсах много разных библиотек типа Socket++, всякие опен-суррс проекты для создания удобного интерфейса и написания сетевых приложений.
Можно руками написать работу с сетью, причем довольно переносимо. Могу пример прислать.
На самом деле +1 за python и тому подобное.
питон не знаю. перл только нюхал
Может вообще написать его под inetd и не париться?
по форку на запрос? ну-ну...
я бы рекомендовал взять готовый tcp-сервер, поддерживающий модули. Если интересует такой — могу дать, но он только под freebsd, ибо юзает kqueue. зато поддерживает модули, всё так динамично и грамотно, даже из под рута не пускается, ругается.
Ещё могу дать свой, он работает и под линуксом на RTSIG, но жутко заточен под http, т. е. из него сделать что-то другое — надо покрамсать много кода.
А вообще, если писать сетевой сервер, то надо под BSD. такая штука эта kqueue клёвая, а линуксовые сигналы как оказалось сосут — при высокой нагрузке будут сегфолты непонятно откуда. :/
линуксовые сигналы как оказалось сосут — при высокой нагрузке будут сегфолты непонятно откудаТы точно в той программе iconv не используешь ? Из-за него, , тоже сегфолты бывают
И что?
---
"Machine cycles are cheap..."
учитывая , думаю дело не в ядре
по форку на запрос?Автор треда не говорил, что необходимо выдерживать n тысяч запросов в секунду. Может ему этого и не надо, тогда писать под inetd самое оно.
А кто говорил, что это сложно? Речь не о том, что это сложно, а о том, что не стоит этого делать без уважительных причин. И на первом месте тут не сложность, а скорее требования к безопасности, предъявляемые к сетевым приложениям.Я бы посоветовал 100 раз подумать, перед тем как начинать писать сетевое приложение на C++.А что там сложного то?
Во-первых, писать утомительно (однообразный, рутинный код).Только и занимаюсь, что сетевыми приложениями на C и C++. Нормальный код, не утомляет.
Во-вторых, страшный и долгий геморрой при отладке.
Геморрой при отладке прямо пропорционален кривизне рук и от других факторов зависит слабо.
За примерами далеко ходить не надо: в POSIX парадигма строк — 0-терминированные последовательности октетов. В С++ парадигма строк — std::string. Так вот, артефакты парадигмы POSIX вылезают в STL в виде необходимости передавать конструкторам файловых потоков имя файла как 0-терминированную последовательность октетов, а вовсе не std::string, и уж тем более не юникодные строки.
Работаешь со временем — обломись, нет в STD C++ ничего на эту тему. А значит, либо обращаешься к POSIX-функциям, тяготеющим к C, либо к нестандартным библиотекам, предоставляющим обёртки к тем же функциям. И вот такой хлам прёт изо всех щелей.
Шобы было счастье, хорошо бы пользовать ровно одну парадигму. Снизу доверху. Но пока что для C++-парадигмы реальной возможности это делать нет (существующие полностью объектно-ориентированные ОС практически нигде не применяются).
А использовать С-парадигму не катит, потому как она есть тёмное прошлое, в котором нет даже принципа "выделение ресурса есть инициализация". А без этого принципа, ресурсы имеют дурную привычку утекать. Живой пример — Oracl'овый OCI. Как он течёт памятью, это песня!
Посмотри на библиотеку ACE.
ACE использовать не советую. Большая библиотека, а значит с кучей багов.
Если нужны обёртки вокруг сокетов, мутексов, потоков и т.д., проще (чем разбираться в чужих интерфейсах) и надёжнее (потому что проще отладить) написать свои.
Шобы было счастье, хорошо бы пользовать ровно одну парадигму.
Развелось, бл%, теоретиков...
Вот именно поэтому хотел узнать, может в юниксах есть приличные ОО-обёртки над сокетами..
Так вот, артефакты парадигмы POSIX вылезают в STL в виде необходимости передавать конструкторам файловых потоков имя файла как 0-терминированную последовательность октетов, а вовсе не std::string, и уж тем более не юникодные строки.
Существуют в природе дибилы, в экспортных функциях их библиотек принимаются параметры в виде STL-контейнеров. Что КАТЕГОРИЧЕСКИ делать нельзя.
Юникодовые строки окейно жуются функциями их понимающими. При чем тут STL — не понял.
Работаешь со временем — обломись, нет в STD C++ ничего на эту тему
А с какой стати в stl что-либо должно быть для ВРЕМЕНИ? Это ведь такая скользкая вещь, к тому же платформозависимая!
Шобы было счастье, хорошо бы пользовать ровно одну парадигму.
Не надо стремиться к вселенскому счастью. Не надо писать классы сокетов и классы таймеров. Ибо это изврат полный, абстракция на пустом месте ради непонятно чего.
Если нужны обёртки вокруг сокетов, мутексов, потоков и т.д.Кстати вот прикольная обёртка, но она не плюсовая.
http://www.dellroad.org/pdel
Правильно. Настоящие пацаны используют исключительно klibc. А реальные пацаны --- пишут свою libc.
---
...Я работаю антинаучным аферистом...
Не просто из любопытства, ты не встречал легковесных TCP/IP стеков?google://"light weight TCP stack"
Может, ты встречал что-то полезное, видел обзоры, мнения и т.п.
---
...Я работаю антинаучным аферистом...
Видел мнение, что первая ссылка - хороший софт.
Ладно.
---
...Я работаю антинаучным аферистом...
Существуют в природе дибилы, в экспортных функциях их библиотек принимаются параметры в виде 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'и у меня возникали только на попытках вызвать из одного метода, блокирующего лок класса, другой, который тоже лок бло
Кстати вот прикольная обёртка, но она не плюсовая.
http://www.dellroad.org/pdel
Это не обёртка, призванная контролировать освобождение ресурсов, если я всё правильно понял.
Правильно. Настоящие пацаны используют исключительно klibc. А реальные пацаны --- пишут свою libc.Это не реальные пацаны. Я написал (для удовольствия) класс, который работает почти как cout. Но вот реализован под чистую машину, без операционки, без использования BIOS. Вот он — по-пацански писал выводимые символы с их атрибутами прямо в видео память. Правда, к этому классу пришлось дописать страничный менеджер памяти, свой new (у меня свободные блоки были огранизованы в сбалансированное дерево, что обгоняло GNU'шный malloc при частом выделении блоков случайного размера, освобождении случайных блоков (среди уже выделенных) и так в цикле, выделение/освобождении; на на менее жёстких тестах превосходство моего new не было так заметно; а сделал бы на красно-чёрном дереве, небось ещё быстрее было бы свой менеджер прерываний, свой менеджер адресных пространств и задач в них, свой запуск ELF'ов, свой переключатель задач (простейший round-robin свой драйвер ATA, свой драйвер ext2, свой IPC на передаче сообщений. Чего своего не было, так это bootstrapping'а. Я решил, что "вытаскивать себя за свои шнурки" — дело мюнхаузенов и авторов GRUB'а. Так что реализовал ELF'овый мультибут. Но всё остальное — делал сам. Даже выяснял доступную память сам, безо всяких BIOS'ов и GRUB'ов. Чисто по-пацански. Записал-прочитал-проверил-записал другое в то же место-прочитал-проверил — обе проверки прошли: тута есть память, пошли к следующему адресу. Учёл ПЗУ 64K-1M, аккуратно обошёл область, куда сам загружен (выясняется по собственному заголовку ELF'а, надо только сделать его загружаемым, что легко реализовать ld-скриптом; а можно меток понаставить на начала/концы загружаемых секций). Вота, вся память, что нашёл — вся моя, никакому BIOS'у под его резервы ни байта не отдал!
Да, освбождение ресурсов тут не причём.
> По двум причинам.
> 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?
Из-за этой мелочи, его приходится хранить отдельно.
---
...Я работаю антинаучным аферистом...
Объясни свою мысль, в случае если контейнеры передаются по ссылке или парой итераторов. Почему этого категорически нельзя делать?
Если либа и программа её использующая используют разные реализации STL, то наступит пиздец. Элементарно, даже std::string может устроить фигню, например с аллокатором проблем не оберешься. Вообще, читай книжки, везде сказано что нельзя. И точка.
В результате бинарные данные нельзя интерпретировать как строки.
И слава Богу.
Это приводит к проблеме из реальной жизни: мне нужно делать регулярный поиск (с регулярным выражением, генерируемым по пользовательскому вводу) по бинарным UDP пакетам.
посмотри исходники grep/egrep.
Это приводит к проблеме из реальной жизни: мне нужно делать регулярный поиск (с регулярным выражением, генерируемым по пользовательскому вводу) по бинарным UDP пакетам.В СОРМе работаешь?
Из-за этого существуют разные API для одного и того же действия, например
Для сравнения по регулярному выражению нет API работающего для строк с нулевыми символами в середине. Если бы для всех задач было бы два API — не вопрос, я бы не возмущался.
3. Любое действие с выделением подстроки требует дополнительной памяти и копирования.
На самом деле, в схеме строка+размер тоже будет дополнительное выделение памяти при создании подстроки — как минимум для размера. Но не только. В многопоточном приложении и даже в однопоточном, если либо строка, либо подстрока не является константной, потребуется копирование и данных строки. Иначе модификация одной из этих строк может привести к модификации в другой, или даже к недействительности другой строки в случае необходимости перераспределения памяти для этой модификации.
Кстати, вопрос.
Почему нет доступной функции, отдающей размер куска, созданного malloc?
Из-за этой мелочи, его приходится хранить отдельно.
Потому что плохо думали, когда стандарты писали.
Если либа и программа её использующая используют разные реализации STL, то наступит пиздец. Элементарно, даже std::string может устроить фигню, например с аллокатором проблем не оберешься. Вообще, читай книжки, везде сказано что нельзя. И точка.
Аргумент понятен. Но это относится к любой линковке объектов, скомпилированных разными компиляторами или линкованных с разными либами, имеющими один и тот же интерфейс. Меня больше интересует почему это нельзя в случае, когда все компоненты собираются на одной платформе одними и теми же средами компиляции под один и тот же ABI и с одними и теми же либами. Это наиболее частая для меня ситуация.
И слава Богу.
Аргумент не ясен. Обоснуйте связь Яхве и нуль-терминированных строк.
посмотри исходники grep/egrep.
Предложение достойное истинного гуру. Мне не надо смотреть. Мне надо, чтобы у меня работало. С наименьшим геморроем разработки и поддержки. Для этого мне нужна стандартная функция, в стандартной либе.
Взять код grep я не могу по лицензионным соображениям — придётся брать GNU grep, а лицензировать свою программу по GPL/LGPL я не могу, так как не определяю лицензионную политику работодателя. А чтобы машинку регулярных выражений написать, мне не нужно заглядывать в код grep. Достаточно книжки по ним (машинкам) и время (гораздо меньшее, чем если бы пришлось разбираться в чужом коде). Проблема в том, что писать это самому не является решением с "наименьшим геморроем разработки и поддержки". На данный момент обошёлся собственным простейшим regexp-matching'ом для обхода нулей в регекспе + regexec по строке, в которой нули заменены пробелами. Такое решение меня не впечатляет, но обладает "наименьшим геморроем разработки и поддержки".
В СОРМе работаешь?
Нет
А жаль...
Занимаюсь RADIUS-протоколом.
Взять код grep я не могу по лицензионным соображениям — придётся брать GNU grep,А в libc от BSD нет разве регулярных выражений?
Или там libpcre какую посмотреть.
Занимаюсь RADIUS-протоколом.Есть специальные библиотеки, которые дают atribute/value пары. Зачем такое богохульство как: "поиск регулярного выражения в бинарных UDP пакетах"? Вообще разработчик RADIUS приложения не должен знать про UDP. Может быть в будущем RADIUS будет по SCTP работать.
А не GPL реализации RE существуют.
А в libc от BSD нет разве регулярных выражений?
А libc в FreeBSD разве не GNU'шная? У меня было впечатление, что во FreeBSD нет собственной среды разработки.
Или там libpcre какую посмотреть.Гляну.
Есть специальные библиотеки, которые дают atribute/value пары. Зачем такое богохульство как: "поиск регулярного выражения в бинарных UDP пакетах"?
Я и сам RADIUS-пакеты разбираю влёт. Но это офигительно дорого. Со всеми оптимизациями, которые я сделал (и для которых использовал собственный тривиальный regexp-matching) я проигрываю в поиске grep'у в несколько раз. А дорогой поиск не годится, так как искать надо по многим мегабайтам и гигабайтам сырых RADIUS-пакетов — у крупных inet,voip,etc.-провайдеров RADIUS-статистики в сутки набирается окиян.
То есть есть тривиальный путь оптимизации — поискать просто regexp'ом по файлу с пакетами, а потом, где есть матчинг, пакет с матчингом разобрать и проверить, то ли нашли. Сейчас у меня реализован недо-вариант этой оптимизации. Сделать её полноценно я не могу из-за неполноты моих regexp-matching процедур. И, как я уже говорил, мой недо-вариант проигрывает grep'у в несколько раз.
А когда этой оптимизации не было и я честно разбирал каждый пакет — тормозило не в несколько раз, а на пару десятичных порядков, по сравнению с тем же grep'ом.
Вообще разработчик RADIUS приложения не должен знать про UDP.
Это спорная позиция. RADIUS-сервер всё-таки UDP пакеты получает. Хотя я не совсем правильно выразился — я ищу, разумеется только в содержимом пакета, а UDP заголовок операционка парсит.
А libc в FreeBSD разве не GNU'шная?Ты издеваешься? Интересно, до появления GNU все сидели без libс и ждали появления GNU?
Я и сам RADIUS-пакеты разбираю влёт. Но это офигительно дорого. Со всеми оптимизациями, которые я сделал (и для которых использовал собственный тривиальный regexp-matching) я проигрываю в поиске grep'у в несколько раз. А дорогой поиск не годится, так как искать надо по многим мегабайтам и гигабайтам сырых RADIUS-пакетов — у крупных inet,voip,etc.-провайдеров RADIUS-статистики в сутки набирается окиян.Не разбирая протокол RADIUS, у тупо грепя может быть и быстрее. Но в конце концов закончится невылавливаемыми багами.
А работу эту надо выполнять не раз в сутки, а круглые сутки, постоянно, по мере прихода данных. Если обработку выполнять постоянно, то можно более точно мониторить загрузку машин, выполняющих эту работу - тупо строить графики загрузки CPU, памяти, I/O. Более предсказуемо прогнозировать когда закончатся вычислительные ресурсы. Там где очень много данных, там periodic jobs не рулят.
Нет.
Из-за этого, GNU не поддерживает некоторых полезных действий, как, например, fgetln.
> У меня было впечатление, что во FreeBSD нет собственной среды разработки.
В зависимости от того, что ты под этим понимаешь.
Если компиляторы, то да, их нет.
С другой стороны, существуют непогнутые компиляторы,
которые никто не мешает задействовать, если это требуется.
---
...Я работаю антинаучным аферистом...
Они даны нам господом богом.
$ 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
*/
---
...Я работаю антинаучным аферистом...
> На самом деле, в схеме строка+размер тоже будет дополнительное
> выделение памяти при создании подстроки — как минимум для размера.
Это мелочь по сравнению с размером подстроки, к тому же,
оно ещё и хранится чаще на стеке, а не в куче.
> Но не только. В многопоточном приложении и даже в однопоточном,
> если либо строка, либо подстрока не является константной,
> потребуется копирование и данных строки.
> Иначе модификация одной из этих строк может привести к модификации в другой,
> или даже к недействительности другой строки в случае необходимости
> перераспределения памяти для этой модификации.
Это случаи, когда без копирования вообще не обойтись,
а если предполагается, что строка измениться не может
(один поток или заперта можно было бы обойтись без копирования,
если бы не идиотский API.
---
...Я работаю антинаучным аферистом...
Не разбирая протокол RADIUS, у тупо грепя может быть и быстрее. Но в конце концов закончится невылавливаемыми багами.Расскажи про баги, которые могут вылезти. Повторяю, алгоритм такой: бинарным регекспом найти некоторое совпадение, просмотреть файл назад в поисках magic'а записи (4 байта родом из /dev/random). Считать всю запись (в начале и в конце записи содержатся по 4 байта длины записи, обязаны совпасть). Запись содержит в том числе, RADIUS-пакет. Разобрать пакет, проверить, удовлетворяет ли он условиям поиска. Да — выдать его. Искать дальше.
А работу эту надо выполнять не раз в сутки, а круглые сутки, постоянно, по мере прихода данных. Если обработку выполнять постоянно, то можно более точно мониторить загрузку машин, выполняющих эту работу - тупо строить графики загрузки CPU, памяти, I/O. Более предсказуемо прогнозировать когда закончатся вычислительные ресурсы. Там где очень много данных, там periodic jobs не рулят.
Там нет периодических работ. Приходит запрос, обрабатывается. Кроме того, записывается на диск. (Для аккаунтинга обработка может реально осуществляться отложено, отдельным от RADIUS-сервера процессом, который читает те же файлики, куда запросы складываются. Пока что никакого поиска по пакетам нет. Но вот звонит абонент, говорит: я в интернет войти не могу. Оператор в web-интерфейсе вбивает временной диапазон поиска ("Так, когда вы последний раз пытались войти?") и условие поиска (в данном случае User-Name=логин абонента). Теперь надо быстренько найти (быстренько — люди ждут) все пакеты RADIUS-обмена и выдать оператору. Оператор смотрит на атрибуты, говорит: у вас деньги кончились, услуга не подключена, пароль не угадали и т.д. Ничего связанного с прогнозированием ресурсов по времени тут нет (есть только прогнозирование требуемых ресурсов аппаратной платформы перед внедрением).
В зависимости от того, что ты под этим понимаешь.
Если компиляторы, то да, их нет.
Имел в виду компилятор, библиотеки, утилиты отладки.
С другой стороны, существуют непогнутые компиляторы,
которые никто не мешает задействовать, если это требуется.
Интересны были именно родные, FreeBSD библиотеки, так как у них лицензия заведомо подходящая.
> услуга не подключена, пароль не угадали и т.д.
Довольно-таки странное техническое решение,
неужели нельзя посмотреть по журналу радиуса?
---
...Я работаю антинаучным аферистом...
Они даны нам господом богом.
Вовсе нет. Они даны нам Томпсоном, Керниганом и прочими "пионэрами" как сказал бы "пионэр" Бутенко.
* 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.
Думаю, что не пойдёт. Хотя это надо уточнять у тех, кто лицензированием занимается.
Это мелочь по сравнению с размером подстроки, к тому же,
оно ещё и хранится чаще на стеке, а не в куче.
Это сильно зависит от реализации.
Это случаи, когда без копирования вообще не обойтись,
а если предполагается, что строка измениться не может
(один поток или заперта можно было бы обойтись без копирования,
если бы не идиотский API.
Интересно какой API придумаешь ты для обхода такой ситуации (без копирования данных строки):
s1 = s2.substr (2);
s2 = "Обана, s1 изменилось ;-O";
>> Если компиляторы, то да, их нет.
> Имел в виду компилятор, библиотеки, утилиты отладки.
Библиотеки есть.
Что подразумевается под утилитами отладки, не знаю.
Очень многие отладочные средства родные или братские (например, из OpenBSD).
>> С другой стороны, существуют непогнутые компиляторы,
>> которые никто не мешает задействовать, если это требуется.
> Интересны были именно родные, FreeBSD библиотеки,
> так как у них лицензия заведомо подходящая.
У меня сейчас нет под рукой FreeBSD.
---
...Я работаю антинаучным аферистом...
>> * notice, this list of conditions and the following disclaimer in the
>> * documentation and/or other materials provided with the distribution.
> Думаю, что не пойдёт. Хотя это надо уточнять у тех, кто лицензированием занимается.
Ну, не настолько сложно уточнить.
А потом, всегда можно уточнить и у авторов.
---
...Я работаю антинаучным аферистом...
>> оно ещё и хранится чаще на стеке, а не в куче.
> Это сильно зависит от реализации.
Ну, в общем, да, только всё равно хранить пару указатель---длина проще, чем копии строк.
>> Это случаи, когда без копирования вообще не обойтись,
>> а если предполагается, что строка измениться не может
>> (один поток или заперта можно было бы обойтись без копирования,
>> если бы не идиотский API.
> Интересно какой API придумаешь ты для обхода такой ситуации (без копирования данных строки):
Там чуть выше написано:
>> Это случаи, когда без копирования вообще не обойтись,
Так можно дойти до анекдота: "Доктор, если я делаю так,
так и так, у меня начинает болеть вот здесь..."
---
...Я работаю антинаучным аферистом...
---
"...Потому что Аллах не ведёт людей неверных."
А как ты лицензии будешь find определять? find вообще не нужен, подскажу: всё, что не находится в каталоге contrib идёт под лицензией BSD или еще более свободной.
Некоторые сомневаются в возможности использования того, что идёт с "advertising clause,"
и пока что только UCB отозвал это требование, а сколько ещё осталось?
Хотя по мне, так это требование не настолько сложно удовлетворить.
---
...Я работаю антинаучным аферистом...
Во-первых, advertising clause не должно волновать в большинстве случаев и конкретно в случае . Во-вторых, 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."
Я не думаю, что за полгода всё настолько сильно изменилось.
---
...Я работаю антинаучным аферистом...
В FreeBSD намного меньше advertising clause, потому что с ними умышленно боролись.
---
...Я работаю антинаучным аферистом...
Пока не можешь чего-то проверить, воздерживайся от написания новых постов.
Если не знать, что ты тесно связан с ними, есть полное право утверждать,
что ты неспособен дать хоть какую-то авторитетную оценку.
---
...Тут приехал бульдозер товарища Оккамы...
Утверждай, мне похуй.
Там чуть выше написано:
>> Это случаи, когда без копирования вообще не обойтись,
Так можно дойти до анекдота: "Доктор, если я делаю так,
так и так, у меня начинает болеть вот здесь..."
Так вопрос-то в том, как API (на C++) будет понимать, что изменения ни исходной, ни результирующей строки после операции substr не будет. Насколько я знаю C++, такое ограничение средствами языка не наложить.
>>>> Это случаи, когда без копирования вообще не обойтись,
>> Так можно дойти до анекдота: "Доктор, если я делаю так,
>> так и так, у меня начинает болеть вот здесь..."
> Так вопрос-то в том, как API (на C++) будет понимать,
> что изменения ни исходной, ни результирующей строки
> после операции substr не будет.
> Насколько я знаю C++, такое ограничение средствами языка не наложить.
А как API будет понимать, что за экраном не будет сидеть человек,
исправляющий значения переменных отладчиком?
---
...Я работаю антинаучным аферистом...
Оставить комментарий
yolki
или всё не так далеко ушло и на плюсах используют socket/bind/listen/etc ?в купе с FD_* макросами?