LINUX.ORG.RU

Сеть IP — когда писать программы лень

 


2

6

Автор этой статьи рассуждает о некоторых способах создания прикладных TCP/IP серверов, крайне редко, к сожалению, используемых в прикладном программировании, которые почти не требуют написания программного кода. Поводом для появления этих коротких заметок явилось намерение напомнить о том, что иногда для того, чтобы описать в программе нечто, по существу своему являющееся достаточно сложным, могут существовать способы выразить эти же вещи намного проще.

>>> Подробности

★★★

Проверено: Shaman007 ()
Последнее исправление: Silent (всего исправлений: 1)

для Ъ, по ссылке написано как делать программы не подходя к компьютеру?

vova7890 ★★★
()
Ответ на: комментарий от demmsnt

На самом деле популярность node.js проистекает за безуспешностью внедрить в браузе еще хоть один язык.

При чем тут браузер? Нода исполняется ВНЕ браузера.

JS лично для меня очень неудобный язык. Есть свои плюшки, да. Но очень плох...

А может готовить не умеете?

anthill
()
Ответ на: комментарий от anonymous

не удивляюсь уже, что последняя абанта тормозит сильнее свисты — видимо, там тоже такие вот быдлокодеры заправляют.

Запостите сюда результаты lspci и lsmod, подскажу, почему.

Orlusha ★★★★
()
Ответ на: комментарий от farafonoff

Может под оффтопом fork не используется, но в юниксах - сплошь и рядом. Это я вам как программист говорю.

A-234 ★★★★★
()

Я не понял, что имелось в виду, когда вы стали описывать трехкомпонентную схему.

мы сделаем вызывающую программу (сервер) parent (и использующую показанный класс chld), которую будем вызывать, например, такой командой:

$ parent child p1 p2 p3

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



И далее:

$ cat /etc/xinetd.d/parent
service parent
{
disable = no
protocol = tcp
wait = no
user = olej
server = /home/olej/parent
server_args = /home/olej/child p1 p2 p3
}



То есть, для вызова программы child из parent нам надо прописать этот child в конфиге. Вот этот момент неясен. Почему бы его сразу не прописать, минуя parent? В чем смысл вызова через parent, если всеравно вызываемую программу приходится жестко прописывать в конфиге?

Xintrea ★★★★★
()

У меня, собственно, только один вопрос - чем безопасные read/write не угодили?

A-234 ★★★★★
()

многие часы бдения над инициализацией socket, установлением соединения

мухослонизм?

FedeX ★★
()
Ответ на: комментарий от Orlusha

Запостите сюда результаты lspci и lsmod, подскажу, почему.

а это не у меня лично, а вообще, в окружении. у меня всё хорошо (не на ubuntu).

anonymous
()
Ответ на: комментарий от anthill

При чем тут браузер? Нода исполняется ВНЕ браузера.

Я чувствую себя инопланетянином. Мне постоянно приходится разжевывать элементарные вещи....

1) Удобно всё писать на одном ЯП

2) Пытались воткнуть в браузер другие языки - не получилось

3) Тогда взяли JS и написали на нем серверсайд

Так доступно?

demmsnt
()

ЛЕНЬ пейсать программы? А на что кушать будете?

ПРИКЛАДНЫЕ программы на Це-пи-пи не пишутся - НАМНОГО ПРОЩЕ использовать Java.

Впрочем - кульхацкерам виднее...

Bioreactor ★★★★★
()

OMFG...

Нет, будучи анонимусом, не могу молчать.

Во-первых, сия статья принадлежит «перу» (клавиатуре) Olej, который является известным апологетом QNX (и по совместительству преподом в Харьковском Авиационном или что-то вроде того). С QNX когда-то всё было хорошо. Сейчас она просто крайне редко используется, есть eCOS/RTLinux/..., есть более убогие поделия типа FreeRTOS и т.д. и т.п. Но факт остаётся фактом. С QNX сейчас всё плохо. Кстати, Olej всегда вызывал у меня глубочайшее полчтение. В QNX он отличнейше разбирается. Но дело нескольно не в этом.

Из «во-первых» вытекает то, что сия статья ориентирована на людей, которые на уровне «ни как» не понимают что использование inetd/xinetd в 2012 находится на уровне «немножечко некрофилия». Наверное вызовет удивление, но есть более простые и надёжные способы. Техника использования суперсерверов полна недочётов и проблем как сучка блох. По этой причине её не используют. Года с 2005-2006. Примерно. С добрым утром, господа!

Во-вторых. Господа, вы не видите очевидных проблем? Ну например приведу одну:

можно научить xinetd запускать новый экземпляр сервера по запросу от нового
клиента (wait=no, по умолчанию: wait=yes). Только это не многопоточный
сервер, как его называют, а ... как бы это лучше назвать по-русски? —
многопроцессный: для каждого нового подсоединяющегося клиента
порождается новая копия процесса сервера. Но, заметьте, что классические
UNIX-сервера, построенные через fork() - они в точности такие же
многопроцессные (собственно, это и было генеральным направлением
построения серверов на протяжении почти 30 лет, до широкого
распространения к концу 90-х годов API pthread_* и техники потоков).

Вот за это надо без суда и следствия отрывать руки. История прошла мимо. И поддержка SMP/HT-реализаций заодно и OpenMP (чай не pthread_* единым живы)... Но дело в другом. Вообще-то в современном процессе-демоне можно найти fork() только в одном месте. При порождении процесса-потомка. Всё. Апеллировать к fork() и уповать на более чем 30-летний опыт не имеет смысла в этом случае. И учить xinetd ни чему не нужно. Нехер глумиться над трупом...

В третьих. Касаемо примеров. Блин... Господа... Мне как-то неловко... Но почему именно ЭТО показано? Примеры заставили прослезиться. Например, ни кто не обратил внимание на то, что в Linux есть возможность использовать всё, что связано с epoll*() при организации сетевого обмена, есть тот же вызов sendfile(), который более эффективен чем куча read()/write() и очень хорошо работает с парой файловых дескрипторов/сокетов, да и c алгоритмом Нагля можно успешно побороться при использовании senfile(). Всё хорошо... Нет. Нам всенепременно mycopy.cc изваять, который похож на полную йухню (которой и является, кстати).

В последних, если уж статья пришла из мира QNX, то почему бы не написать про более интересные вещи, специфичные для реализации QNX, ту же QNet. Зачем «ЭТО» было вынесено на главную L.O.R?

P.S. Комментировать полностью этот слегка подтёсанный под «современность» докУмент откровенно «не стоит». Жаль времени. И да... Шаман — идиот, который явно не в курсе что он тянет на главную. Уберите его от «программирования» как можно дальше.

anonymous
()
Ответ на: комментарий от Bioreactor

Как хорошо...

ПРИКЛАДНЫЕ программы на Це-пи-пи не пишутся - НАМНОГО ПРОЩЕ использовать Java.

... что об этом «наипросвещённейшем» мнении не знают ни создатели GTK+/GNOME (там всё-таки по большей части именно С), ни создатели Mozilla & Open-liblreOffice, там всё-таки С++.

Если бы они об этом «мнении» зналои, то сидеть бы нам и без нормальго браузера и без нормального офисного пакета. Единственное «место», где более чем дохера Java во всех видах — соляра. Пользуется бешеной популяностью (где-то... наверное...).

anonymous
()

Когда программы писать лень

Когда программы писать лень - пьётся пиво на диване. Это первое. Второе. Jon Snader, «Effective TCP/IP Programming», Addison-Wesley Это по поводу сетевого программирования вообще и xinetd в частности.

mirr0r
()
Ответ на: комментарий от Xintrea

Так и сделано.

Почему бы его сразу не прописать, минуя parent?

Да ни что не мешает. Здесь, собственно parent является неким обозначением самого по себе сервиса в целом для всей системы. Пусть будет httpd. А вот обработка запросов будет реализована процессом-потомком или child'ом (пусть это будет http-request).

Т.е., в системе будет некий самопальный httpd, который будет на самом деле реализован через http-request. Именно он будет отрабатывать запросы пользователей. Ну или несколько вариантов http-request, это не столь суть важно.

Собственно именно «благодяря» такому подходу и тому, что изначально inetd позволял зачудительнейше монтировать бэкдоры, Rad Hat метнулась переписывать его и создала слегка более защищённый xinetd. От которого в дальнейшем то же отказались, как только появилась возможгность.

Ведь ни что не мешает заменить существующий в системе child (мы договорились его для примера называть http-request) на что-то несколько подправленное. Т.е., в системе будет жить тот же http-request, который при обращении к нему спец. запросом, будет открывать например, бэкдор. Проблема это была... Реальная проблема.

anonymous
()
Ответ на: комментарий от A-234

ЛОЛШТО?!? Ой-вэй!!!

Может под оффтопом fork не используется, но в юниксах - сплошь и рядом. Это я вам как программист говорю.

Ну, судите сами:

1. fork() крайне не выгоден. Гораздо выгоднее в части управления (как минимум порождения) процессов механизм потоков. Да и в дальнейшем именно «потоком» рулить проще. Но у него есть один небольшой недостаток — он _относительно_ сложен. По этой причине, есть п.2

2. Для более простого, но менее гибкого в части управления распараллеливания есть OpenMP.

3. Что потоки, что этот Ваш fork(), который Вам почудился, основаны в Linux на системном вызове clone(), который является «сердцем» в порождении потомков. Его не используют напрямую, только косвенно, но тем не менее, без него ни fork() ни pthread_create() не реализуются.

4. В оффтопе для порождения потоков есть CreateThread(). Для общего образования прочтите хотя бы статью в MSDN, а то неудобно «программисту» это объяснять. Само собой что CreateThread из WinAPI ни как не соотносится к clone(). Но и там все понимают что «нитью» (ещё их называют light-weight proccess) рулить проще, чем целым процессом.

Повторю ещё раз. fork() используется в современных программах-демонах например. Один раз. Чтобы породить процесс-потомок. И всё.

anonymous
()
Ответ на: комментарий от farafonoff

Гы-гы-гы...

также юниксовый ipc.

Что именно не используют?!? «Юниксовый IPC»?!?

Тогда что такое сами по себе sockets, как ни один из видов этого самого «юниксового IPC»??? Может, хоть приличия ради, перед такими заявами в обсуждении статьи про «программирование» прочтёте того же Стивенса? А то мне вот хочется вопрос задать — над Вами Ваш браузер не ржот? )))

Точно так же по-вашему и Memory Mapped Files/Semaphores/signals/file locks/pipes/unix sockets/shared memory segments/message queues/FIFOs... не используются? Вот это новость... Ай да lor! Linuxокапец России... )))

anonymous
()
Ответ на: ЛОЛШТО?!? Ой-вэй!!! от anonymous

1. fork() крайне не выгоден.

Спорно. По большому счёту, вся разница в разделении пространства VM, если процесс-ребёнок ничего особенного не делал и не потребовалось много copy-on-write действий, то особой разницы и нет с нитью, кроме как бОльшей защищённости родителя от детей.

Casus ★★★★★
()
Ответ на: комментарий от Casus

И "да" и "нет".

Спорно. По большому счёту, вся разница в разделении пространства VM, если процесс-ребёнок ничего особенного не делал и не потребовалось много copy-on-write действий, то особой разницы и нет с нитью

Почему «да». Потому что как я и писал выше, порождение процесса идёт посредством clone(). Разница есть. Но она заключается только в том, что порождаемый процесс или поток-потомок наследует от родителя. Всё хорошо написано в clone(2), даже добавить нечего.

А почему «нет». А потому что потоку-потомку придётся проще. Во-первых, в случае с fork() мы получаем две идентичные копии адресного пространства, стека, кода, как для потомка так и для родителя (считайте два одинаковых процесса на исполнении). В случае с потоком мы получаем разделяемые данные, открытые файлы и прочие ресурсы, раздельные рабочие каталоги, обработку сигналов, UID/EUID, GID/EGID... Проще по аналогии. Если после fork() у нас получается два идентичных человека, которые живут похожей жизнью, то в случае с pthread_* мы просто к мозгам одного человека подключаем дополнительные руки-ноги. Пространство VM используется по-разному. Ну и как следствие, накладные расходы на fork() выше порождения потока. Помнится я тестировал в своё время эти два варианта. fork() тормозил в 3-4 раза. Зависело от загрузки системы, но мне, помнится, всё это не по нраву пришлось.

кроме как бОльшей защищённости родителя от детей.

Ммм... Немного спорно. Пришибить процесс можно в принципе как угодно. Хоть сигналом. Влезть в адресное пространство процесса посложнее, но в принципе, это зависит от ситуации. Оно и с потоком не так просто без позволения это сделать. В случае с процессом, кстати, с IPC можно подзапариться, если нужны какие-то средства коммуникации. В случае с потоками всё это разруливается куда как проще. Так что, здесь вопрос открытый. Зависит от конкретного контекста использования кода.

И уж совсем просто всё решается (кроме управления потоками!) c OpenMP. Так что, в принципе, выбор есть что использовать, но вот форкаться это немного более дорого для системы.

anonymous
()
Ответ на: комментарий от Casus

Вот из-за таких недоумков как ты, xinetd и находится в забвении. А ведь идея лежащая в основе его просто прекрасна! Автор молодец, покажи этим выродкам кузькину мать!

anonymous
()
Ответ на: комментарий от anonymous

Вот из-за таких недоумков как ты, xinetd и находится в забвении. А ведь идея лежащая в основе его просто прекрасна! Автор молодец, покажи этим выродкам кузькину мать!

Для этого сначала ему придется научиться писать на C++ хотя бы на 3-, ибо по ссылке какая-то быдлокодерская содомия.

anonymous
()

нахрена же такой треш постить в виде новости...

mashina ★★★★★
()
Ответ на: комментарий от memnek

нет, пишется макрос на лиспе, который генерирует что нужно

Лисп тоже попса.

harper
()
Ответ на: OMFG... от anonymous

Из «во-первых» вытекает то, что сия статья ориентирована на людей, которые на уровне «ни как» не понимают что использование inetd/xinetd в 2012 находится на уровне «немножечко некрофилия».

А кроме 'не модно' будут какие нибудь аргументы?

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

Что может быть проще: прочитал со STDIN, записал в STDOUT?

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

anonymous
()
Ответ на: комментарий от anonymous

А при чём здесь «модно-немодно»?

Ответ был дан здесь.

Сеть IP — когда писать программы лень (комментарий)

Это не «не модно». Это «небезопасно». У Вас всё будет хорошо в пределах Вашего localhost'а. Но вот за его пределами всё может быть очень плохо. И да, порождать процессы-потомки через xinetd по накладным расходам, это намного тяжелее fork(). Зачем цепляться за старьё?

anonymous
()
Ответ на: комментарий от anonymous

Ты можешь отличить обучающие примеры от production-кода? Вот когда научишься - тогда можешь потявкать на автора! Какое-то сборище олухов, придрались к какой-то фигне не поняв сути! Xinetd идеален там, где нет высоконагруженных систем: embedded systems, различные внутренние сервисы, да тот же домашний сервер... Только больной на всю голову придурок будет пихать веб-сервер, который работает демоном внутрь адсл модема, когда он там нужен 0.0001% времени работы этого самого модема. Нигде в статье не предлагается использовать xinetd в качестве high-load, причом здесь форк??? Какие нафиг в 3-4 раза медленнее, нет слов просто....

anonymous
()
Ответ на: комментарий от anonymous

[#] Ответ на: комментарий от Xintrea 06.05.2012 9:52:33 Так и сделано.

Короче, здесь. Админы, а что, так сложно прикрутить редактирование постов?

anonymous
()
Ответ на: комментарий от anonymous

Из пещеры! Бегом!

Только больной на всю голову придурок будет пихать веб-сервер, который работает демоном внутрь адсл модема, когда он там нужен 0.0001% времени работы этого самого модема.

lighttpd давным-давно и крайне успешно используется в том же asus wl-500 gp/gpv2! И не для задач конфигурирования самого по себе устройства, а для отдачи контента.

Xinetd идеален там, где нет высоконагруженных систем: embedded systems, различные внутренние сервисы, да тот же домашний сервер...

Простите что интересуюсь, милейший, но вы мудак от Бога или Вас таким жизнь сделала? Embedded systems внезапно стани _НЕНАГРУЖЕННЫМИ_?!? «Внутренние сервисы» и прочие localhost'ы это здорово и круто. Но что проще — писать сразу и грамотно или заниматься онанированием над кодом? Тот же lighttpd написан руками и по этой причине сугубу по-фигу где ему работать — хоть на MIPS, хоть на Intel. И ни какого рукоблудия с запуском.

Нигде в статье не предлагается использовать xinetd в качестве high-load, причом здесь форк??? Какие нафиг в 3-4 раза медленнее, нет слов просто....

fork() всплыл в обсуждении. А по поводу бустрее-медленнее, так я открою Вам тайну. Всё будет (как и писал) зависит от нагруженности системы. Если ей, бедолаге, ни бзднуть и пёрнуть, то наблюдать за забавными попытками системы что-либо сделать не втыкает. Система должна работать. И как можно быстрее. Но вот стресс-тесты ни кто не отменял, а они весьма показательны бывают.

Если не предлагается high-load, то тогда я вынужден Вас уволить. Причин две. Во-первых, на хрен нужна система, которая не может обеспечить high-load by default, которую надо подтачивать. Во-вторых, тратить на такого рода «развлечения» деньги можно, но не нужно. Гораздо проще написать код раз и грамотно и не драть себе мозги с разного рода некрофилией.

anonymous
()
Ответ на: комментарий от eagleivg

потому что он лучше чем всякие shm (хотя бы тем что количество shm жестко устанавливается в ядре и может кончиться в неудачный момент), пайпы просто не решают задачу, сообщения очень медленные, а над сокетами еще нужно писать обертки. Так вот dbus это и есть система оберток.

farafonoff ★★
()
Ответ на: комментарий от KennyMinigun

посмотрите apache(fork) vs nginx. везде где хочется распараллеливания - лучше использовать pthreads, они быстрее и легче. единственное разумное применение fork - fork/exec, но иначе в unix никак.

farafonoff ★★
()
Ответ на: комментарий от A-234

И зря он используется в юниксах. Масштабируются они не очень хорошо, fork - главная причина overcommit в ядре (что плохо само по себе). Приложения написанные и использованием fork не могут иметь общие кэши данных, что замедляет работу.

farafonoff ★★
()
Ответ на: Гы-гы-гы... от anonymous

из всего названного зоопарка хорошо живут только sockets, mmap, pipes. Остальное лучше не трогать - трупниной воняет. Семафоры медленные (по сравнению с pthread mutex), сигналы deprecated (не безопасно с точки зрения разделяемых библиотек, например), shm ограничены в количестве (ограничение на всю систему) message queues медленные. pthreads заменяют все это намного более эффективными механизмами общей памяти и атомарных операций.

farafonoff ★★
()
Ответ на: комментарий от Casus

А зачем защищать родителя от детей, если дети часть родителя? Связь родителя с детьми - слабое место в этой схеме. Если надо что-то кэшировать - эта архитектура уже ломается. На самом деле так делали потому, что для обозначения ошибок применялись сигналы (которые приходят в процесс, а не в поток), и разные процессы нужны были чтобы изолировать родителя от сигналов детей. Но сигналы плохи сами по себе (очень медленные).

farafonoff ★★
()
Ответ на: Так и сделано. от anonymous

Ведь ни что не мешает заменить существующий в системе child (мы договорились его для примера называть http-request) на что-то несколько подправленное. Т.е., в системе будет жить тот же http-request, который при обращении к нему спец. запросом, будет открывать например, бэкдор. Проблема это была... Реальная проблема.

Понял.

Но для продакшен серверов, для которых ПО пишется персонально под конкретную задачу, это ни разу не проблема. Так что сия техника имеет право на существование, и я себе закладочку сделал.

Xintrea ★★★★★
()
Ответ на: комментарий от duin

Заставляет задуматься статья ...

Над чем?

Над тем как сегодня все печально в девелоперстве вообще и в сетевом в частности???

Тот же Снейдер писал, что люди разучились писать простые и надежные проги.

Ну а если народ всерьез утверждает, что для сетевых приблуд нет языка лучше жабы (а уж тем более жабаскрипта), начинаешь понимать, куда летим.

Чичас холиварщики набросятся, рвать будут за любимую икону. =)

mirr0r
()
Ответ на: комментарий от farafonoff

pthreads заменяют все это намного более эффективными механизмами общей памяти и атомарных операций.

... а так же замечательно парадигмой crashing one crashes all, ага.

no-dashi ★★★★★
()
Ответ на: комментарий от farafonoff

Приложения написанные и использованием fork не могут иметь общие кэши данных, что замедляет работу.

man mmap смотрит на тебя как на непрочитавшего его.

no-dashi ★★★★★
()
Ответ на: комментарий от farafonoff

посмотрите apache(fork) vs nginx

Спасибо, поржал. :)

Именно Апач сейчас использует нити для обработки запросов, а nginx — нет.

baka-kun ★★★★★
()
Ответ на: комментарий от farafonoff

А зачем защищать родителя от детей

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

baka-kun ★★★★★
()
Ответ на: комментарий от Casus

особой разницы и нет с нитью

Там самое тяжелое — создание полноценного дескриптора процесса вместо нити. Причем в древние времена linux fork() был относительно дороже, чем в солярке или bsd.

baka-kun ★★★★★
()
Ответ на: ЛОЛШТО?!? Ой-вэй!!! от anonymous

Повторю ещё раз. fork() используется в современных программах-демонах например. Один раз. Чтобы породить процесс-потомок. И всё.

Это называется не «повторю еще раз», а «простите, совсем забыл». В предыдущем своем посте Вы писали: "...уже давно никто не использует, как и fork()". И речь у нас шла не о линуксе конкретно а о юниксе вообще. При чем тут линуксовая реализация?

A-234 ★★★★★
()
Ответ на: комментарий от farafonoff

Вот понадобилось мне в программе запустить и прочитать вывод системного скрипта. Ничего проще и универсальнее fork/exec лично я придумать не могу.

A-234 ★★★★★
()
Ответ на: комментарий от A-234

fork - клевая штука, но к сожалению непереносимая (под оффтопом ему аналога нет). Также fork годится только для негуёвых приложений.

navrocky
()
Ответ на: комментарий от Bioreactor

ПРИКЛАДНЫЕ программы на Це-пи-пи не пишутся - НАМНОГО ПРОЩЕ использовать Java.

Это в твоём сферическом вакууме такая статистика. Оглянись и подсчитай, сколько прикладных программ написано и на каких языках.

navrocky
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.