utros
20.10.2011 03:55 pedobook
Киньте в меня ссылкой в ман или расскажите как решить вот такую задачу:
Есть программка %program%, которая принимает keep-alive подключения на порту 1234. Задача: запустить несколько экземпляров этой программы на одной машинке и раздавать tcp-соединения, приходящие на порт 1234 хоста процессам этой программы.
Весь код есть, язык — c.
Я подозреваю, что мне нужно будет из своего процесса открыть соединение, форкнуться нужное количество раз и из дочерних процессов и сделать exec. Но я пока не до конца понимаю, какие тут подводные камни и вообще хотелось бы получше разобраться как вся эта магия работает.
сделай чтобы твоя мега-программа работала с stdin/stdout и подсунь её под inetd
Каждый процесс будет работать с кучей соединений и я не очень хорошо понимаю как разруливать их при таком подходе.
а, с кучей... тогда тебе в любом случае придётся модифицировать исходную программу. Или чтобы она была многопоточной, или чтобы сама форкалась после listen(2). Я не уверен даст ли нужный результат использование SO_REUSEADDR | SO_REUSEPORT.
В идеале хотелось бы, чтобы всё работало как в nginx (фиксированное количество воркеров и один мастер-процесс).
Многопоточности очень не хочется. Форкаться на каждое соединение тоже не ок, ибо тормоза будут адские.
http://www.kegel.com/c10k.html
Я и не предлагаю форкаться на каждое соединение, сделай listen(2) и форкнись сколько тебе нужно, а потом уже в каждом процессе запускай цикл с poll/kqueue/epoll/whatever. Как-то так все это и работает, насколько я понимаю.
А если хочешь более точного контроля — принимай соединения в родительском процессе, а потом отдавай дескрипторы чайлдам вручную через unix socket
годно
xinetd. ?
да, читал. Интересная вещь.
Ну я об этом и написал в /0.
Что можно почитать по этому поводу?
нет, ты писал о немного другом. тебе надо чтобы сначала программа делала listen(2), а потом уже форкалась, тогда у всех чайлдов будет listening socket и они все смогут делать на него accept(2). А в /0 ты написал о внешней программе, которая нафоркается и каждый чайлд запустит программу которая будет делать listen(2) (что, впрочем, делается одним циклом на sh, никакой программы писать не нужно). И в твоём варианте без добавления SO_REUSEADDR|SO_REUSEPORT на сокет в вызываемой программе слушающий сокет получит только первая которая успеет, остальные получат EADDRINUSE от bind(2).
man fork. остальное ничем не отличается от однопроцессного варианта.
Ну да, кривовато как-то сформулировал /0.
И да, спасибо.