Форум программистов, компьютерный форум, киберфорум
C# .NET
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.95/21: Рейтинг темы: голосов - 21, средняя оценка - 4.95
58 / 24 / 6
Регистрация: 26.09.2010
Сообщений: 241

Решил сделать свой асинхронный многопоточный сервер

31.12.2016, 11:38. Показов 4483. Ответов 10
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Итак. Цель создать асинхронный многопоточный сервер для MMOFPS (онлайн шутер от первого лица) на C#.

Соответственно план такой:
1) Сервер должен быть асинхронный на сокетах
2) Выдерживать одновременно 2500-3500 подключений
3) Думаю использовать несколько потоков:
первый - слушать подключение новых клиентов или отключение существующих, периодически пинговать не отвалился ли клиент;
второй - принимать/отправять пакеты;
третий - серверная игровая логика. (может быть совместить со вторым?);
четвертый - работа с БД;
4) Масштабируемость сервера. Как и за счет чего осуществить?

Предполагаю не использовать Socket.BeginAccept, так как этот метод вроде как медленный, это так? Какие есть еще варианты?
Хотя на самом сайте майкрософта это как раз используется в примере https://msdn.microsoft.com/ru-... .110).aspx

Как избежать использования while(true){} ?

Прокомментируйте что я в плане написал правильно, а что нет.

В общем, помогайте)))
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
31.12.2016, 11:38
Ответы с готовыми решениями:

Асинхронный и многопоточный - одно и то же?
асинхронный и многопоточный - одно и то же?

Асинхронный сервер. Нужно сделать его многопоточным
Создал асинхронный сервер. Нужно сделать его многопоточным. От каждого клиента приходит как минимум 5 данных, которые нужно записать и в...

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

10
Эксперт .NETАвтор FAQ
 Аватар для Storm23
10427 / 5157 / 1825
Регистрация: 11.01.2015
Сообщений: 6,226
Записей в блоге: 34
31.12.2016, 11:43
Цитата Сообщение от Sergio-X86 Посмотреть сообщение
Прокомментируйте что я в плане написал правильно, а что нет.
В общем, помогайте)))
Помогаю - судя по вашим вопросам и планам, проект провальный, закрывайте.
0
58 / 24 / 6
Регистрация: 26.09.2010
Сообщений: 241
31.12.2016, 12:09  [ТС]
Цитата Сообщение от Storm23 Посмотреть сообщение
Помогаю - судя по вашим вопросам и планам, проект провальный, закрывайте.
Проект больше для учебной цели. Аналогично я начинал изучать C#, когда вообще ничего не понимал. Постепенно ставя себе задачи, и решая их, я достиг хорошего уровня в нем. Теперь решил сетевой частью заняться также ставя себе задачи. Поэтому прошу помочь мне в начинании.
0
Эксперт .NETАвтор FAQ
 Аватар для Storm23
10427 / 5157 / 1825
Регистрация: 11.01.2015
Сообщений: 6,226
Записей в блоге: 34
31.12.2016, 12:30
Sergio-X86,
1) Определитесь какой сетевой протокол вы собираетесь использовать. Вы сходу взялись за TCP как я понимаю. Хотя обычно для таких задач используется UDP.
2) Разработайте протокол обмена. Он должен минимизировать траффик и в то же время передавать достаточно информации для однозначного позиционирования игрока.
3) Разработайте модель интерполирования. Как для движения игрока, так и для выстрелов. Для затравки почитайте например здесь https://habrahabr.ru/post/135306/ (первое что попалось в гугле, специально не отбирал)
4) Забудьте про 3500 игроков онлайн. Вообще. Навсегда. Это не реально в шутере. Настройтесь на 20-30 игроков максимум.
5) Забудьте пока про потоки. Потоки в последнюю очередь. Да и про БД тоже забудьте... Какое БД в шутере? БД годится максимум для того, что бы запоминать количество фрагов.
6) Ну а так, да, Socket.BeginAccept подходит
0
Эксперт .NET
6691 / 4102 / 1607
Регистрация: 09.05.2015
Сообщений: 9,574
31.12.2016, 12:48
Класс SocketAsyncEventArgs
High Performance .NET Socket Server Using Async Winsock
C# SocketAsyncEventArgs High Performance Socket Code
0
58 / 24 / 6
Регистрация: 26.09.2010
Сообщений: 241
31.12.2016, 14:40  [ТС]
Цитата Сообщение от Storm23 Посмотреть сообщение
1) Определитесь какой сетевой протокол вы собираетесь использовать. Вы сходу взялись за TCP как я понимаю. Хотя обычно для таких задач используется UDP.
2) Разработайте протокол обмена. Он должен минимизировать траффик и в то же время передавать достаточно информации для однозначного позиционирования игрока.
3) Разработайте модель интерполирования. Как для движения игрока, так и для выстрелов. Для затравки почитайте например здесь https://habrahabr.ru/post/135306/ (первое что попалось в гугле, специально не отбирал)
4) Забудьте про 3500 игроков онлайн. Вообще. Навсегда. Это не реально в шутере. Настройтесь на 20-30 игроков максимум.
5) Забудьте пока про потоки. Потоки в последнюю очередь. Да и про БД тоже забудьте... Какое БД в шутере? БД годится максимум для того, что бы запоминать количество фрагов.
6) Ну а так, да, Socket.BeginAccept подходит
1) Да, мне нужен TCP чтобы гарантированно доставлять пакеты.
2) Протокол обмена я разработаю, есть реальный опыт работы с этим.
3) С этим тоже смогу разобраться, хорошая статья.
4) Шутер MMOFPS с "открытым" миром, так что нужно именно такое количество подключений. Ну и с прицелом на будущее использовать сервер для MMORPG. Я понимаю, что есть факторы, когда может в одном месте собраться и 7000 игроков, но уже второстепенная задача.
5) Ок. Разберусь сначала с коннектом/обменом информацией.

Самая важная для меня задача, в которой я пока не компетентен, это подключение к серверу большого количества клиентов, получение/отправка пакетов, обработка их (ну с этим понятно более менее), слежение за тем подключен ли клиент. При этом на сервере будет проверка коллизий, проверка и управление открыванием дверей, и прочих механизмов.
0
11 / 11 / 11
Регистрация: 08.07.2013
Сообщений: 43
31.12.2016, 22:14
Не просто так делают залы по 18-20 человек, в современных MMOFPS используется и TCP, и UDP.
TCP для взаимодействия с UI, создание залов, чат.
UDP для передвижения по карте, стрельба.

Про 7000 можете забыть сразу, тем более на c#, необходимо будет поднять несколько серверов.
Про архитектуру MMORPG можете почитать на хабре, там есть ряд интересный статей, например от разработчиков Mail.Ru.
0
Злой няш
 Аватар для I2um1
2136 / 1505 / 565
Регистрация: 05.04.2010
Сообщений: 2,881
31.12.2016, 22:20
Цитата Сообщение от Sergio-X86 Посмотреть сообщение
1) Да, мне нужен TCP чтобы гарантированно доставлять пакеты.
TCP для реализации игр в реальном времени НЕ подходит. Основная проблема в его гаранте доставки пакетов, что влечет за собой ужасную производительность. Довод: на основе UDP возможно реализовать эффективный TCP-аналог под конкретную задачу. Миксовать TCP и UDP - тоже плохая идея. И от системы предсказания действий наверное не избавиться.

Цитата Сообщение от Sergio-X86 Посмотреть сообщение
2) Протокол обмена я разработаю, есть реальный опыт работы с этим.
Если был бы опыт в разработке многопользовательских сетевых игр, таких вопросов на форуме не было бы. Высокоуровневый протокол обмена сообщениями над UDP/TCP - основа производительности игры в реальном времени.
Пара неочевидных общих (будут варьироваться от задачи) вещей:
- Сообщение должно содержать размер, тип (опкод) и номер в очереди (или его аналог). Опкод - это целое число, уникальный идентификатор действия, которое было совершено.
- Сообщение должно влазить в размер пакета. Об игроке отправляется не все состояние, а только какое-то одно крошечное и определенное (текущая позиция например, три целых числа).
- Сообщение должно быть максимально маленького размера. Медленная и кривая стандартная двоичная сериализация здесь не подойдет. Вообще не подойдет что-угодно, связанное с рефлексией. Сообщение должно сериализоваться/десериализоваться очень быстро и при этом весить очень мало. Например есть такой тип base 128 varint, который меняет свой размер в зависимости от размера данных, которые в нем содержаться. Проще говоря в простом случае число 5 занимает 1 байт, а число 12345 - 2 байта. В сложном случае применяется например еще ZigZag кодирование - это когда -12345 тоже весит 2 байта.
- Текст по возможности лучше вообще не помещать в сообщения. В противном случае использовать ASCII или целые коды. Для чата лучше использовать отдельный чат-сервер и никак не валидировать на валидность сообщения.
- В сообщениях только информация о событиях и никакой графики, звука, текстов и подобной медиа.
- Сообщение, когда приходит, становится в очередь, а не сразу же в этот момент обрабатывается.
Пока думаю хватит. Этот список можно увеличивать до белого каления. Не говоря о способностях сервера выдерживать этот ддос.

Цитата Сообщение от Sergio-X86 Посмотреть сообщение
Выдерживать одновременно 2500-3500 подключений
Это очень много. Логика сервера будет очень сложная - разработка игр основана на применении огромного числа хаков (далеко неочевидных) ради производительности.
Например, хорошая практика использовать компонентно-ориентированное программирование вместо ООП. Имеется ввиду никаких ссылок и наследования. Наследование - это операции над виртуальной таблицей типов, что плохо для производительности, особенно когда иерархия большая; с другой стороны композиция намного лучше наследования для реализации механик игры. Ссылки плохо влияют на производительность и эффективность размещения данных в памяти, лучше использовать указатели, а еще лучше использовать простое число ID и менеджер контента, который умеет искать объект по его ID. Довод: не будет в коде строк вида Player.Info.DetailInfo.SomeSpecificInfo.SomeValue.SomeValue2.SomeValue3...SomeValueN (пример утрирован, на самом деле все еще хуже получается, так как надо еще как минимум кастить к нужному типу), которые очень сильно просаживают производительность, учитывая что это еще и свойства, к которым долгое обращение.

Цитата Сообщение от Sergio-X86 Посмотреть сообщение
Шутер MMOFPS с "открытым" миром, так что нужно именно такое количество подключений.
Цитата Сообщение от Sergio-X86 Посмотреть сообщение
Думаю использовать несколько потоков
Несколько потоков не выдержит такую нагрузку + в винде есть потолок на их количество. Тут нужны хитрые реализации с загрузкой каждого ядра через очередь асинхронных задач, которые не будут вообще потоки выделять - они создадутся заранее, на старте сервера, в пуле потоков. Не уверен, что стандартная реализация планировщика задач справится. Особенно если начать распределять задачи между серверами. А отлаживать такое - ад, только логирование и поиск.

Цитата Сообщение от Sergio-X86 Посмотреть сообщение
Предполагаю не использовать Socket.BeginAccept, так как этот метод вроде как медленный, это так? Какие есть еще варианты?
Откуда такая информация? При работе с удаленными ресурсами (сокеты, база данных, файлы...) лучше всегда использовать асинхронные вызовы и лучше те, которые представлены из коробки (так как они оптимизированы под эту задачу, чем городить свой медленный велосипед). Потому что это позволит процессору сделать какую-нибудь другую задачу, пока сокет ожидает входящую информацию.
Преждевременная оптимизация - дорога в ад. Нужно сперва написать прототип, который будет худо-бедно держать 5 пользователей и гонять 25 Гб траффика в час в виде JSON/XML, а потом уже пытаться его оптимизировать. К тому моменту будет уже список основных проблем и варианты их решения, основанные на интеграционных тестах, а не "построение несуществующего дома из несуществующих палок".

Цитата Сообщение от Sergio-X86 Посмотреть сообщение
это подключение к серверу большого количества клиентов
Одновременное подключение? Лучше использовать очередь.

Цитата Сообщение от Sergio-X86 Посмотреть сообщение
Как избежать использования while(true){} ?
Никак, если работу нужно повторять бесконечно, пока работает сервер. На клиенте цикл вовсе не нужен - достаточно ожидать входящее сообщение из другого потока, которое само себя перезапускает, не убивая при этом поток.

Цитата Сообщение от Sergio-X86 Посмотреть сообщение
Самая важная для меня задача, в которой я пока не компетентен
Это оценка собственных сил.
0
58 / 24 / 6
Регистрация: 26.09.2010
Сообщений: 241
31.12.2016, 23:12  [ТС]
Спасибо всем за понятные развернутые ответы! Теперь более менее понятно в какую сторону двигаться. Если кто-нибудь допишет еще рекомендации буду только рад =)
0
 Аватар для m0nax
1274 / 975 / 113
Регистрация: 12.01.2010
Сообщений: 1,971
01.01.2017, 00:41
напиши для начала крестики-нолики, чтоб была 100% стабильность всех действий игрока и очередность
считаешь себя крутым, хочется хардкора - крестики-нолики, но добавь drug&drop чтоб другой игрок мог видеть в реальном времени перемещение твоего крестика/нолика (без лагов по вине кода)
этих 2 задач более чем достаточно чтоб успокоится и либо стать экспертом, либо забить на сетевые игры в принципе
0
58 / 24 / 6
Регистрация: 26.09.2010
Сообщений: 241
01.01.2017, 01:09  [ТС]
Цитата Сообщение от m0nax Посмотреть сообщение
напиши для начала крестики-нолики, чтоб была 100% стабильность всех действий игрока и очередность
считаешь себя крутым, хочется хардкора - крестики-нолики, но добавь drug&drop чтоб другой игрок мог видеть в реальном времени перемещение твоего крестика/нолика (без лагов по вине кода)
этих 2 задач более чем достаточно чтоб успокоится и либо стать экспертом, либо забить на сетевые игры в принципе
На основе чужого сервера я недавно написал мультиплеерный tower defence. По сути сервер готовый, я лишь создал нужные мне структуры пакетов, прием/отправку данных, и серверную логику. Сервер ожидает пока игроки подключатся к лобби, потом для двоих кто нажал "поиск игры", создается собственно матч игрок против игрока (PVP), идет несколько волн крипов трех видов (2 по земле и 1 по воздуху), соответственно можно строить башни тоже трех видов, крипов и башни можно апгрейдить по 2 уровня вверх, при этом меняется их 3д моделька. На сервер рассчитывается передвижение крипов, проверяется расстояние от пушки до крипа которого можно атаковать, рассчитывается сколько снарядов вылетит при атаке, и какой снаряд добьет крипа (уничтожит на клиенте). Все изменения само собой сразу отображаются у обоих игроков. Сервер считает время раунда, считает количество начисленных очков за различные действия, количество отнимаемого у базы игрока HP. Извилистый путь тоже считается на сервере по ключевым точкам, прямым и кривым. Но дело в том, что сервер на C++, и он чужой. А мне нужен свой и на C#.
Еще, я в онлайн шутере в Стиме сделал полноценный режим с закладкой и разминированием бомбы как CS:GO, а также зомбимод + много доработок в готовых режимах деафматч и классическая контра. Поэтому с пакетами, и минимизацией траффика работать умею. Само собой с авторизацией клиента на сервере работал, в том числе с использованием PHP+MySQL. А вот в часть, где происходит подключение сокетов я не лез, так как все вполне неплохо работает.
Но мне свое надо, надо дальше расти, изучить и эту часть серверных технологий. И как-то C# больше по душе чем C++.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
01.01.2017, 01:09
Помогаю со студенческими работами здесь

Решил сделать локальный TCP прокси-сервер. Как делать переадресацию?
Решил сделать для себя простой локальный прокси-сервер на ТСР-сокетах. По ТСР-части вопросов нет, она более-менее работает. HTTP-запросы от...

Как сделать свой сервер?
Здравствуйте! Мне надо сделать свой веб сервер, у меня есть лишний ПК, доступ к интернет(с динамическим IP), надо разместить сайт,...

Как сделать свой почтовый сервер на PHP?
Как сделать свой почтовый сервер на PHP, типа mail.ru (понятно что не такой крутой и для меньшего количества пользователей). Создать...

Как сделать свой dns сервер ? Для перенаправления по имени к ип ?
В нашей локальной сети поднят dhcp и там же настроен днс в windows server 2008 r2. Я хочу сделать свой собственный список адресов. Типа: ...

Я решил Задачу на Произвольную Пространственную Систему Сил, решил систему из 5 неизвестных, КАК СДЕЛАТЬ ПРОВЕРКУ РЕШЕНИЯ ?
КАК СДЕЛАТЬ ПРОВЕРКУ РЕШЕНИЯ ?? ПРОВЕРКУ НЕ СИСТЕМЫ, А САМОГО РЕШЕНИЯ, то есть сумму моментов всех сил относительно каких точек...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
11
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Работа со звуком через SDL3_mixer
8Observer8 08.02.2026
Содержание блога Пошагово создадим проект для загрузки звукового файла и воспроизведения звука с помощью библиотеки SDL3_mixer. Звук будет воспроизводиться по клику мышки по холсту на Desktop и по. . .
SDL3 для Web (WebAssembly): Основы отладки веб-приложений на SDL3 по USB и Wi-Fi, запущенных в браузере мобильных устройств
8Observer8 07.02.2026
Содержание блога Браузер Chrome имеет средства для отладки мобильных веб-приложений по USB. В этой пошаговой инструкции ограничимся работой с консолью. Вывод в консоль - это часть процесса. . .
SDL3 для Web (WebAssembly): Обработчик клика мыши в браузере ПК и касания экрана в браузере на мобильном устройстве
8Observer8 02.02.2026
Содержание блога Для начала пошагово создадим рабочий пример для подготовки к экспериментам в браузере ПК и в браузере мобильного устройства. Потом напишем обработчик клика мыши и обработчик. . .
Философия технологии
iceja 01.02.2026
На мой взгляд у человека в технических проектах остается роль генерального директора. Все остальное нейронки делают уже лучше человека. Они не могут нести предпринимательские риски, не могут. . .
SDL3 для Web (WebAssembly): Вывод текста со шрифтом TTF с помощью SDL3_ttf
8Observer8 01.02.2026
Содержание блога В этой пошаговой инструкции создадим с нуля веб-приложение, которое выводит текст в окне браузера. Запустим на Android на локальном сервере. Загрузим Release на бесплатный. . .
SDL3 для Web (WebAssembly): Сборка C/C++ проекта из консоли
8Observer8 30.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
SDL3 для Web (WebAssembly): Установка Emscripten SDK (emsdk) и CMake для сборки C и C++ приложений в Wasm
8Observer8 30.01.2026
Содержание блога Для того чтобы скачать Emscripten SDK (emsdk) необходимо сначало скачать и уставить Git: Install for Windows. Следуйте стандартной процедуре установки Git через установщик. . . .
SDL3 для Android: Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 29.01.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами. Версия v3 была полностью переписана на Си, в. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru