0 / 0 / 0
Регистрация: 31.05.2017
Сообщений: 33
1

Серверный движок

31.05.2017, 12:52. Показов 4790. Ответов 80
Метки нет (Все метки)

привет у меня такой вопрос, делаю игру и пишу собственный серверный движок. подскажите в правильном ли я направлении двигаюсь? подойдет ли данный подход для написания своих серверов (чат, авторизация, игровой сервер)?
вот пример кода сервера авторизации который я набросал
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;
 
namespace autorization
{
    class Program
    {
        static string log = null;
        static string pas = null;
 
        static void Main(string[] args)
        {
            start_server();
        }
 
        static void start_server()
        {
            // Устанавливаем для сокета локальную конечную точку
            IPEndPoint ipPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 8005);
 
            // Создаем сокет Tcp/Ip
            Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            // Назначаем сокет локальной конечной точке и слушаем входящие сокеты
            try
            {
                server.Bind(ipPoint);
                server.Listen(10);
                Console.WriteLine("Сервер запущен.");
                // Начинаем слушать соединения
                while (true)
                {
                    Console.WriteLine("Ожидаем соединение через порт {0}", ipPoint);
                    // Программа приостанавливается, ожидая входящее соединение
                    Socket client = server.Accept();
                    // Мы дождались клиента, пытающегося с нами соединиться
                    byte[] receive = new byte[1024];
                    for (int i = 0; i < receive.Length; i++) { receive[i] = 0; }
                    client.Receive(receive);
 
                    string message = Encoding.UTF8.GetString(receive);
                    //Указываем на конец строки с нужными данными
                    int count = message.IndexOf(";;;5");
                    if (count == -1) { continue; }
                    //Создаем переменную, в которой будет храниться очищенное сообщение
                    string clear_message = "";
                    for (int i = 0; i < count; i++) { clear_message += message[i]; }
                    //Начинаем делить очищенное сообщение на отдельные части
                    string[] split = clear_message.Split(':');
 
                    log = split[0];
                    pas = split[1];
 
                    Console.WriteLine("Подключение клиента: " + "Логин: " + log + " Пароль: " + pas);
 
                    if (log == "admin" && pas == "1234")
                    {
                        Console.WriteLine("Данные успешно подтверждены.");
                        // Отправляем ответ клиенту
                        string msg = "yes" + ";;;5";
                        byte[] send = new byte[1024];
                        send = Encoding.UTF8.GetBytes(msg);
                        client.Send(send);
                    }
                    else
                    {
                        Console.WriteLine("Указанные Логин или Пароль не найдены в Базе Данных.");
                        // Отправляем ответ клиенту
                        string msg = "no" + ";;;5";
                        byte[] send = new byte[1024];
                        send = Encoding.UTF8.GetBytes(msg);
                        client.Send(send);
                    }
 
                    Console.WriteLine("Сервер завершил соединение с клиентом.");
                    client.Shutdown(SocketShutdown.Both);
                    client.Close();
                }
            }
            catch (Exception ex) { Console.WriteLine(ex.ToString()); }
        }
    }
}
__________________
Помощь в написании контрольных, курсовых и дипломных работ здесь
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
31.05.2017, 12:52
Ответы с готовыми решениями:

Серверный процесс
Здравствуйте! При старте программы, я создаю новый серверный процесс ( с помощью класса Process)....

Реализовать клиент-серверный чат (консольная версия)
Реализовать клиент-серверный чат (консольная версия) со следующими возможностями: • При...

Как переписать программу под серверный вариант
Добрый день. Подскажите как переписать(написать) прогу, чтобы установив ее на сервере, смогли...

Реализовать клиент серверный проводник для просмотра файлов на компьютере
Нужно реализовать клиент серверный проводник для просмотра файлов на компьютере. Вопрос : как...

80
Эксперт .NET
9336 / 6699 / 1081
Регистрация: 21.01.2016
Сообщений: 25,271
31.05.2017, 12:54 2
wwworking, это говнокод. Для самообучения и микро-серверков оно пойдёт (с натяжкой). Для каких-то сложных вещей - нет, ибо мгновенно превратится в неуправляемую забагованную кашу.
0
0 / 0 / 0
Регистрация: 31.05.2017
Сообщений: 33
31.05.2017, 13:16  [ТС] 3
как тогда написать норм код на с#? нужно так же использовать сокеты и передачу пакетов в байтах?
0
Эксперт .NET
9336 / 6699 / 1081
Регистрация: 21.01.2016
Сообщений: 25,271
31.05.2017, 13:26 4
wwworking, для начала нужно уметь писать код на C# А это время на изучение и практику. Просто так, потому что захотелось, не получится.

Ну какие технологии использовать - зависит от задачи. Можно сокеты, можно WCF, можно WebAPI или вообще шину сообщений типа AKKA.NET. Если речь про игрушку, то тут только сокеты, так всё остальное сильно сложнее, чем для игрушки может понадобиться.
0
0 / 0 / 0
Регистрация: 31.05.2017
Сообщений: 33
31.05.2017, 13:34  [ТС] 5
ну я хотел бы сделать 2д ммо игру, вот думаю как это все реализовать. я так понял что мне нужно дальше все это дело делать через сокеты? стоит ли мне использовать методы Send \ Recive? или же нужно писать собственную конструкцию для передачи данных? не пойму в чем проблема моего кода? в том что данные передаются массивом байт?
0
Эксперт .NET
9336 / 6699 / 1081
Регистрация: 21.01.2016
Сообщений: 25,271
31.05.2017, 14:07 6
wwworking, начните с чего-нибудь попроще. С чата, например. Он же вам в вашей игрушке всё равно понадобиться.

В коде плохо всё. Не имеет смысла расписывать.

Цитата Сообщение от wwworking Посмотреть сообщение
стоит ли мне использовать методы Send \ Recive? или же нужно писать собственную конструкцию для передачи данных?
Вот это я не понял, если честно.

Можно использовать не голые сокеты, а небольшую надстройку: TcpClient\TcpListener. Данные классы умеют заворачивать обмен данными в стрим (NetworkStream), с которым значительно удобнее работать (особенно, если завернуть его в BinaryReader или что-то своё), при этом не теряется "низкоуровневость".
0
0 / 0 / 0
Регистрация: 31.05.2017
Сообщений: 33
31.05.2017, 14:36  [ТС] 7
Usaga непойму почему мой код неправильный? 1.правильно ли я устанавливаю соединение с клиентом, создавая сокет сервера? 2.правильно ли я выношу в отдельный поток подключившегося клиента, создавая сокет клиент? или тут нужно как-то сделать это через Thread? 3. Что касается приема \ оправки сообщений, правильно ли то что данные упаковываются в массив байт, или нужно как-то по другому передавать данные? я имею в виду вот эти строки кода
C#
1
2
3
byte[] receive = new byte[1024];
                    for (int i = 0; i < receive.Length; i++) { receive[i] = 0; }
                    client.Receive(receive);
C#
1
2
3
byte[] send = new byte[1024];
                        send = Encoding.UTF8.GetBytes(msg);
                        client.Send(send);
4)что касается Receive \ Send то я хотел бы узнать правильно ли использовать данные методы или же нужно писать собственные?
0
TheGreatCornholio
1238 / 718 / 283
Регистрация: 30.07.2015
Сообщений: 2,392
31.05.2017, 16:52 8
Для создания игр лучше использовать готовые движки типа этого.
Также, я бы посоветовал погуглить, чтобы посмотреть готовые реализации.
А самый актуальный для Вас совет - не прыгать выше головы, а изучать .net последовательно, не торопясь, и копить опыт.
0
Эксперт .NET
9336 / 6699 / 1081
Регистрация: 21.01.2016
Сообщений: 25,271
31.05.2017, 16:54 9
wwworking, вы не используете потоки, всё синхронно. Вот тут:

C#
1
2
3
byte[] receive = new byte[1024];
                    for (int i = 0; i < receive.Length; i++) { receive[i] = 0; }
                    client.Receive(receive);
... вы принимаете сообщение и даже не проверяете сколько реально байт было получено. Кстати, вы же в курсе, что массив, при создании, принудительно обнуляется исполняющей средой?

Вот тут:

C#
1
2
byte[] send = new byte[1024];
                        send = Encoding.UTF8.GetBytes(msg);
... вы точно понимаете, что делаете?..

А это:

C#
1
2
3
4
                    string[] split = clear_message.Split(':');
 
                    log = split[0];
                    pas = split[1];
... откуда такая железобетонная уверенность, что split будет содержать не менее двух элементов?

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

Ну и всё остальное в таком же духе.

Потому я вам и сказал, что рановато ещё браться за игры. Потренируйтесь на малом и простом.
0
0 / 0 / 0
Регистрация: 31.05.2017
Сообщений: 33
31.05.2017, 17:25  [ТС] 10
1) вы не используете потоки, всё синхронно. \ с эти нужно будет разобраться
2) вы принимаете сообщение и даже не проверяете сколько реально байт было получено \ как устроить такую проверку и для чего? у меня есть только смутные догадки
3)Кстати, вы же в курсе, что массив, при создании, принудительно обнуляется исполняющей средой? \ если вы про эту строку for (int i = 0; i < receive.Length; i++) { receive[i] = 0; } то тут я специально очищаю массив чтобы он был пустой и готовый к работе
4)... вы точно понимаете, что делаете?.. \ тут я записываю в массив переменную msg попутко переводя ее в байты
5)... откуда такая железобетонная уверенность, что split будет содержать не менее двух элементов? \ потому как на клиенте структура отправки данных идет следующим образом : "log + ":" + "pas" + ";;;5", где ";;;5" это конец строки и все что идет после этого знака отсекается
6)Да и вообще, весь приём и обработка сообщений идёт в вечном, непрерываемом (нормальным образом) цикле, который после первого же исключения завершится. \ ага тут тоже надо додумывать )
7)Потому я вам и сказал, что рановато ещё браться за игры. Потренируйтесь на малом и простом. \ это и есть мало. сделать хотя бы сервер авторизации или чат сервер )
0
Эксперт .NET
9336 / 6699 / 1081
Регистрация: 21.01.2016
Сообщений: 25,271
31.05.2017, 17:34 11
Цитата Сообщение от wwworking Посмотреть сообщение
если вы про эту строку for (int i = 0; i < receive.Length; i++) { receive[i] = 0; } то тут я специально очищаю массив чтобы он был пустой и готовый к работе
Ещё раз: массив создаётся пустым и готовым к работе.

Цитата Сообщение от wwworking Посмотреть сообщение
тут я записываю в массив переменную msg попутко переводя ее в байты
Тут вы записываете в переменную send массив, полученный от Encoding.UTF8.GetBytes(msg);, а старый (на килобайт) просто теряете. Это говорит об очень поверхностных познаниях языка. Тут не до 2D ММО.

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

Цитата Сообщение от wwworking Посмотреть сообщение
вы не используете потоки, всё синхронно. \ с эти нужно будет разобраться
Если вы не отличаете, где используете потоки, а где нет, то тут нужно браться за учебник, а не за чат для игры.
0
483 / 396 / 68
Регистрация: 14.02.2014
Сообщений: 1,930
31.05.2017, 17:35 12
wwworking, ))) MMO игра из одного игрока...это сильно
0
0 / 0 / 0
Регистрация: 31.05.2017
Сообщений: 33
31.05.2017, 18:21  [ТС] 13
ну понятно что это набросок, что бы понять че как и куда двигаться, я так понял что для сервака мне понадобятся сокеты, делегаты, потоки Thread ?

Добавлено через 6 минут
стоит ли использовать протокол передачи данных тср? или же нужно делать собственный?
0
Эксперт .NET
9336 / 6699 / 1081
Регистрация: 21.01.2016
Сообщений: 25,271
31.05.2017, 18:33 14
Цитата Сообщение от wwworking Посмотреть сообщение
стоит ли использовать протокол передачи данных тср? или же нужно делать собственный?
Всё что вы "наваяете" будет сделано либо поверх TCP, либо поверх UDP. Для вашего протокола это будет транспортным уровнем. Любое общение между сервером и клиентом строится по какому-то языку (протоколу). Поскольку у вас там уже какая-то структура сообщений имеется, то свой протокол вы уже сваяли (по крайней мере, в зачаточном состоянии).

Написать взамен TCP не получится. А вот поверх него - да. Не путайтесь.
0
0 / 0 / 0
Регистрация: 31.05.2017
Сообщений: 33
31.05.2017, 18:55  [ТС] 15
Usaga да у меня уже каша в голове от разной информации, давайте попробуем конкретизировать ситуацию. Я начинаю делать свой сервер авторизации который будет получать от клиента логин\пароль, проверять данные и если они верны отправлять клиенту положительный ответ. если нет - отрицательный. И так приступая к написанию : 1)чтобы соединить клиент и сервер я буду использовать сокеты
C#
1
Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
2)Подключившегося клиента я должен вынест в отдельный поток который будет выполнять различные действия с клиентом, при этом основной поток, сокет сервера будет продолжать работу паралельно ожидая входящие подключения и переводя их в отдельные потоки. Тут мне стоит использовать
C#
1
Socket client = server.Accept();
или же восспользоваться Threade \ ThreadePool? 3) После того как мы отправили клиента в свою "комнатку" где он будет заниматься своими делами начинаем думать а как же нам оргонизовать процесс приема и передачи сообщений. сейчас я у себя исспользовал конструкцию
C#
1
2
3
4
string msg = "yes" + ";;;5";
                        byte[] send = new byte[1024];
                        send = Encoding.UTF8.GetBytes(msg);
                        client.Send(send);
где мною были пременены методы Send и Receive класа сокет(если я не ошибаюсь), так вот мне продолжать использовать данную конструкцию или нужно что-то другое? и нужно-ли эту конструкцию так же выделять в какой-то отдельный поток?
0
Эксперт .NET
9336 / 6699 / 1081
Регистрация: 21.01.2016
Сообщений: 25,271
31.05.2017, 19:34 16
wwworking, server.Accept() только принимает входящее подключение и возвращает объект класса Socket ассоциированного с данным клиентом. С потоками оно никак не связано. Используйте Thread/Task для создания потока в котором данный клиент будет обслуживаться.

Используйте TcpClient\TcpListener, а не Socket, или явно заворачивайте Socket в NetworkStream. Это ответ на 1) и 3).
0
0 / 0 / 0
Регистрация: 31.05.2017
Сообщений: 33
31.05.2017, 19:41  [ТС] 17
Usaga нашел данный материал https://metanit.com/sharp/net/6.1.php, но в коментах пишут о каких-то проблемах поэтому я что-то за сомневался в данном подходе, вот и начал с сокетов. + там еще есть тема https://metanit.com/sharp/net/6.2.php
0
Эксперт .NET
9336 / 6699 / 1081
Регистрация: 21.01.2016
Сообщений: 25,271
01.06.2017, 03:50 18
wwworking, вчитайтесь, что пишут в комментариях и что я рекомендую. Немного разные вещи. Я не предлагал использовать StreamReader, о котором пишут там. А вот использовать NetworkStream да завёрнутый в BinaryReader намного удобнее, чем с буферами вручную возиться, как вы хотитет.
0
0 / 0 / 0
Регистрация: 31.05.2017
Сообщений: 33
01.06.2017, 10:53  [ТС] 19
Usaga спасибо за ответы, думаю так и поступлю, а насколько этот подход будет правильным \ популярным? это же не из древности? таким много где пользуются?
0
Эксперт .NET
9336 / 6699 / 1081
Регистрация: 21.01.2016
Сообщений: 25,271
01.06.2017, 10:56 20
wwworking, в C# такое используется часто для работы со сторонними сервисами. Для взаимодействия с C#-сервисами удобно использовать WCF, но для игрушек это слишком "тяжёлый" протокол. Потому вариант с сокетами - норм.
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
01.06.2017, 10:56

По нажатию на кнопку данные из input записываются в сессию+серверный редирект на другую страницу
На странице есть input(text) и кнопка. По нажатию на кнопку данные из input записываются в...

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

Серверный апгрейд
И так у меня на данный момент 350вт блок питания, материнка Asus P5QL SE S775, проц Dual Core E5200...

серверный шкаф
здравствуйте, посоветуйте серверный шкаф для 2 серверов, 1 tower ш230 х д380 х в450 и HP 2)ш380 х...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2021, vBulletin Solutions, Inc.