Какую модель на основе сокетов я должен использовать для множества одновременных соединений? - PullRequest
3 голосов
/ 11 ноября 2010

Мне нужно знать, какая модель на основе сокетов лучше всего подходит для серверов с множеством одновременных подключений, точно так же, как на сервере MMORPG.

Я читал о c10k, но что мне следует использовать, если дляпример мой сервер позволил бы только 5000 клиентов одновременно?Блокировка сокетов, с резьбой (один поток на клиента)?Неблокирующие розетки, без резьбы?цикл обработки всех клиентов только в нескольких потоках?IOCP?

Каковы преимущества и недостатки, короче говоря?Я уже гуглил, но не нашел конкретной статьи «против» обо всех этих моделях.

Или есть более простой способ решения проблемы c10k?

Платформа: Windows XP

Ответы [ 4 ]

4 голосов
/ 11 ноября 2010

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

Недавно я собрал некоторые из причин, по которым IOCP предпочел другие модели, доступные в Windows, и они доступны здесь, в моем блоге здесь .

Часто «сложность» указывается в качестве причины, позволяющей избежать IOCP, но, если честно, если вы делаете что-то кроме «потока на соединение», код в любом случае будет достаточно сложным. У меня есть бесплатный набор кода C ++ с примерами серверов , на который вы могли бы взглянуть, он выполняет всю работу IOCP за вас, и примеры серверов являются хорошей отправной точкой для вашего собственного кода. Вы можете получить его у здесь .

В качестве альтернативы у меня также есть бесплатная (для некоммерческого использования) сменная серверная платформа, которая может вас заинтересовать. С WASP вы просто пишете dll с некоторыми конкретными точками входа, и я делаю все сетевые вещи для вас ... Смотрите здесь для загрузки и здесь для учебника.

Какую бы модель вы ни выбрали, ЕДИНСТВЕННАЯ и самая важная вещь, ИМХО, состоит в том, чтобы начать выполнять тестирование производительности и нагрузки с 0 ДНЯ. Таким образом, вы ЗНАЕТЕ, сколько одновременных соединений вы можете поддерживать на целевом оборудовании, и вы можете быстро определить неуместные дизайнерские решения, которые вызывают это падение. Это легко расточить параллелизм вашего сервера. См. здесь для получения дополнительной информации.

Поскольку Джей упомянул ENet ... Я обнаружил, что наш ENet-сервер на базе IOCP хорошо работает со стандартным клиентским кодом Enet. Но помните, ENet разработан, чтобы быть одноранговым протоколом, и поэтому есть некоторые проблемы, когда вы начинаете пытаться использовать его на сервере. Со стандартным кодом ENet у вас, по сути, однопоточный сетевой насос, который просто не может сравниться с масштабируемостью, которую вы получаете от IOCP. В итоге я переписал код обработки протокола ENet с нуля, чтобы работать с асинхронным вводом-выводом и IOCP, и это нетривиальный объем работы. В настоящее время я делаю новую версию этого кода, в которой в качестве основы используется последний протокол ENet, и, надеюсь, он будет доступен в начале 2011 года с полным сравнением производительности со стандартным кодом ENet, используемым в большом количестве одновременных ситуаций сервера соединений.

1 голос
/ 11 ноября 2010

Решение о том, каким образом взаимодействовать с сервером, в значительной степени зависит от того, как клиент будет отправлять данные, какой тип данных отправляется, ожидаемой скорости передачи и структуры трафика.

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

Если у вас есть многопользовательский пакман, вы можете отправитьмаленькие пакеты, когда направление меняется, поэтому оно не будет постоянным, но оно будет пакетным.

Затем вы можете решить, должны ли вы гарантировать порядок пакетов и насколько важен каждый отправленный пакет, как вам потребуетсявзглянуть на TPC или UDP. (http://www.skullbox.net/tcpudp.php)

Если вы хотите поддерживать 5000 клиентов, то такое количество потоков может быть проблемой производительности, в зависимости от того, сколько памяти, но, что более важно, сколько ядер выи интенсивность обработки процессора, но, скорее всего, это приведет к снижению производительности.

Тогда вы можетепосмотрите на select() (http://www.lowtek.com/sockets/select.html),, который позволит меньшему количеству потоков обрабатывать нагрузку, но, если вы используете потоковую передачу, это может стать проблемой, поскольку выделенный поток имеет больше смысла.

То, как решить, какая из них лучше, зависит от того, какую игру вы пишете, поскольку обе могут быть полезны, в зависимости от сценария.

0 голосов
/ 07 декабря 2010

Вы должны использовать IOCP и сокетный ввод / вывод (любой простой ввод / вывод), используя ReadFile и WriteFile.

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

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

Порты завершения ввода-вывода почти ничего не стоят, и это также относится к нескольким потокам. Так что, если вы можете делать свои биты достаточно быстро, то на самом деле нет предела тому, сколько завершений ввода / вывода может обработать NT-движок. Ваше интернет-соединение, вероятно, будет в первую очередь насыщенным.

0 голосов
/ 11 ноября 2010

Вы читали эту статью?

Я провел аналогичное исследование и нашел библиотеку eNet . Я полагаю, что он использует Select () вместо любого из более новых методов, но есть много пользователей, которые указали, что у них были очень хорошие результаты с ним. Изменить не составит труда, если вам абсолютно необходимо столько одновременных подключений.

...