Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > RAW socket multithreaded сервер. Помогите!


Автор: kreez 16.11.2002, 01:05
Привет!
Я начинающий программер и у меня в процессе работы возникли кое-какие вопросы, с которыми я
решил к Вам пристать. Вобщем, я разрабатываю сетевую стратегическую игру (сервер под Линукс, клиенты - под Винды) на С++. Все построено на RAW ip пакетах для экономии трафика. Сервер многозадачный - я выбрал потоки, а не процессы потому, что каждому потоку требуется определенный доступ к общим данным (например, карты игрового поля и т.д.), а взаимодействие процессов - слишком гиморная вещь, тогда как потоки по умолчанию используют разделяемые ресурсы динамической памяти. Схема примерно такова: есть главный поток, в котором существует сокет, и несколько постоянно действующих дочерних потоков - по одному для каждого зарегистрированного игрока-клиента. Каждый из дочерних потоков отвечает только за конкретного игрока и выполняется все время (то есть он не просто запускается в определенное время, выполняется и завершается, как это принято, а запускается, когда игрок с новым именем зарегистрировался, и выполняется до тех пор, пока "королевство" игрока не "уничтожат" или оно само не "вымрет"). AI выполняет все функции по управлению "королевством" игрока, а игрок может в это дело вмешиваться как считает нужным. Это позволяет "королевству" существовать даже когда самого игрока нет в онлайне. Так вот я не знаю как заставить каждый поток принимать только те неструктурированные RAW пакеты, которые отправляются от имени игрока, с которым связан данный поток, не трогая остальные. Дело в том, что в Линукс ядро автоматом шлет все входящие неструктурированные
пакеты первому попавшемуся потоку (сокет один для всех потоков), принимающему пакеты с заданным протоколом
(255 - для RAW в данном случае). А мне нужно чтоб не было путаницы в пакетах и чтоб поток игрока "Федя" не получал пакетов,
посланных игроком "Вася". Вопрос: как это сделать?
Я был бы очень благодарен, если бы Вы кинули мне на мыло линки, где можно посмотреть и скачать различные реализации
библиотек RAW сокетов, поддерживающих многозадачность, на С++ (под Линукс есессно).
И вообще, где можно получить квалифицированную помощь лично от знающего толкого программиста (советы, хинты), по мейлу?

Автор: dim 16.11.2002, 07:16
Дело в том, что не получится чтобы одни RAW socket пакеты приходили туда, а другие туда, поскольку такого понятия как порт в них нету, поэтому RAW сокет биндается к IP адресу. Порты же распознают протоколы верхнего уровня, такие как TCP и UDP, и порты образно говоря используются для того чтобы привязать определенный сокет к определенному процессу. Если же ты будешь слушать RAW пакеты в общем случае тебе придется пропускать через себя весь IP траффик, что на фоне с мифической борьбой по экономии траффика занятие не из приятных. Кроме того тебе придется парсать каждый пакет, чтобы отличать свои от чужих. Как по мне то более разумное решение это создавать обычние TCP connections (ну можешь UDP юзать если так переживаешь за размер траффика). При использовании TCP вообще все менингиты отпадают, потому что для каждого коннекшена будет создаваться свой сокет, которые удобно разместить в соотв. потоке.

Автор: dim 16.11.2002, 07:35
Кстати еще вопрос: как ты делаешь потоки в Linux-е, если их там нету, а многопоточность реализовывается через форканье процессов?

Автор: kreez 16.11.2002, 10:10
Я использую банальный linuxthreads. Это конечно связано с накладными расходами (плюс один управляющий процесс), но зато избавлет от геморроев с IPC :). А вообще есть достаточно много библиотек с разнами реализациями threads-ов. В любом случае как при использованиии потоков, так и при использованиии процессов используется системник clone() :). И все таки можно же, наверное, заставить прогу распределять пакеты между нужными потоками? Чисто на логическом уровне ане на уровне kernel IP implementation'а.

Автор: Baa 16.11.2002, 12:48
Совет:
прикрепи сигнатуру к пакетам и при получении перенаправляй пакет нужному потоку.

Автор: kreez 16.11.2002, 12:58
Это, конечно, все хорошо... Data в IP пакет я могу вставить любые... Но как реализовать перенаправление? Как заставить сервак (родительский поток) переслать полученный пакет уже выполняющемуся дочернему потоку?

Автор: HexoGenus 17.11.2002, 03:19
Цитата(kreez @ 16.11.2002, 04:58)
Это, конечно, все хорошо... Data в IP пакет я могу вставить любые... Но как реализовать перенаправление? Как заставить сервак (родительский поток) переслать полученный пакет уже выполняющемуся дочернему потоку?

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

Автор: kreez 17.11.2002, 18:31
Смысл в том, что объекты в программе создаются в динамической памяти, которая по умолчанию шарится между потоками (с процессами это просто так не проходит - дам надо задействовать средства IPC)... Потоки по ходу выполнения могут менять эти области памяти как им вздумается, получается, что в любой момент времени любой поток знает все об остальных, так что со взаимодействием между игроками проблем нет. Вопрос: как передать данные в уже выполняющийся поток, не используя динамическую память?

Автор: Baa 18.11.2002, 10:43
Используй pipes.

Автор: kreez 18.11.2002, 10:48
Зачем мне каналы? Можно проще - через разделяемую память...

Автор: dim 19.11.2002, 08:06
Цитата
Совет:
прикрепи сигнатуру к пакетам и при получении перенаправляй пакет нужному потоку.

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

Автор: kreez 19.11.2002, 10:07
По большому-то счету на производительность можно пока забить... Главное заставить работать ту схему, которую я описал выше... Вопрос: как?

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)