Форум программистов, компьютерный форум, киберфорум
C# для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.70/30: Рейтинг темы: голосов - 30, средняя оценка - 4.70
0 / 0 / 0
Регистрация: 31.05.2017
Сообщений: 33

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

31.05.2017, 12:52. Показов 6851. Ответов 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
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
31.05.2017, 12:52
Ответы с готовыми решениями:

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

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

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

80
0 / 0 / 0
Регистрация: 31.05.2017
Сообщений: 33
04.06.2017, 19:22  [ТС]
Студворк — интернет-сервис помощи студентам
вот что у меня получилось на данный момент, но выдаёт ошибку:"поток был не доступен для записи". в результате чего клиент не получает ответ сервера сообщение.
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
namespace server_login
{
    class Package
    {
        public Package(string Login, string Password)
        {
            this.Login = Login;
            this.Password = Password;
        }
        public string Login { get; private set; } //Логин
        public string Password { get; private set; } // Пароль
    }
}
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
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.IO;
using System.Threading.Tasks;
using System.Net;
 
 
namespace server_login
{
    class ClientObject
    {
        public TcpClient Client;
        public ClientObject(TcpClient tcpClient) { Client = tcpClient; }
        public void ClientHandler()
        {
            NetworkStream Stream = null;
            try
            {
                Stream = Client.GetStream();
                using (var reader = new BinaryReader(Stream))
                {
                    // считываем данные из потока
                    string login = reader.ReadString();
                    string password = reader.ReadString();
                    // создаем по полученным данным объект пакета
                    Package package = new Package(login, password);
                    // обрабатываем полученные данные от клиента
                    Console.WriteLine("подключение клиента: {0}, пароль: {1}", package.Login, package.Password);
                }
 
                string Message = "server ok";
                   // отправляем ответ клиенту
                using (var writer = new BinaryWriter(Stream))
                {
                    // создаем по полученным данным объект пакета
                    writer.Write(Message);
                    writer.Flush();
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
 
            finally
            {
                if (Stream != null) Stream.Close();
                if (Client != null) Client.Close();
            }
        }
    }
}
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
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.IO;
using System.Threading.Tasks;
using System.Net;
 
 
namespace server_login
{
    class Program
    {
        const int Port = 5006;
        static void Main(string[] args)
        {
            TcpListener server = null;
            try
            {
                server = new TcpListener(IPAddress.Parse("127.0.0.1"), Port);
                server.Start();
 
                Console.WriteLine("Ожидание подключений...");
 
                while (true)
                {
                    TcpClient tcpClient = server.AcceptTcpClient();
                    ClientObject client = new ClientObject(tcpClient);
 
                    var task = Task.Run(() => { client.ClientHandler(); });
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            finally
            {
                if (server != null) server.Stop();
            }
        }
    }
}
вот код юнити клиента:
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
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using System.Net;
using System.Net.Sockets;
using System.Text;
using UnityEngine.SceneManagement;
using System;
using System.IO;
public class ScriptLoad01 : MonoBehaviour 
{
    public InputField InputBox1;
    public InputField InputBox2;
    public GameObject ErrorPanel;
 
    const int PORT = 5006;
    const string ADDRESS = "127.0.0.1";
    public void OnClick()
    {
        string log = InputBox1.text;
        string pas = InputBox2.text;
 
        TcpClient tcpClient = null;
 
        try
        {
            string login = log;
            string password = pas;
 
            tcpClient = new TcpClient(ADDRESS, PORT);
 
            NetworkStream stream = tcpClient.GetStream();
 
            using (var writer = new BinaryWriter(stream))
            {
                writer.Write(login);
                writer.Write(password);
                writer.Flush();
            }
 
            using (var reader = new BinaryReader(stream))
            {
                string Message = reader.ReadString();
 
                if (Message == "server ok")
                {
                    SceneManager.LoadScene(1);
                }
                else
                {
                    ErrorPanel.SetActive(true);
                    Debug.Log("Неправильный логин или пароль");
                }
            }
        }
        catch(Exception ex)
        {
            Debug.Log(ex.Message);
        }
        finally
        {
            tcpClient.Close();
        }
    }
}
0
Эксперт .NETАвтор FAQ
 Аватар для Storm23
10428 / 5158 / 1825
Регистрация: 11.01.2015
Сообщений: 6,226
Записей в блоге: 34
04.06.2017, 19:40
Цитата Сообщение от wwworking Посмотреть сообщение
выдаёт ошибку:"поток был не доступен для записи"
В методе ClientHandler (кстати лучше его назвать HandleClient) вы создаете BinaryReader внутри блока using. После выхода из этого блока, вызывается метод Dispose ридера, который закрывает все ресурсы, связанные с ридером, в том числе и поток поверх которого ридер открыт. То есть после выхода из блока using - поток оказывается закрыт и далее вы не можете работать с потоком.
Поэтому нужно :
1) Либо использовать только один блок using для всех ридеров/райтеров:
C#
1
2
3
4
5
using (var br = new BinaryReader(stream))
using (var bw = new BinaryWriter(stream))
{
   //...
}
2) Либо использовать вот эту перегрузку конструктора, которая позволяет не закрывать низлежащий поток.
0
0 / 0 / 0
Регистрация: 31.05.2017
Сообщений: 33
04.06.2017, 19:59  [ТС]
Storm23, не разобрался как сделать через перезагрузку, если можешь напиши пример плизз, пока попробую сделать в 1м блоке

Добавлено через 1 минуту
Storm23, сделал в одном блоке. теперь выскакиевает:Не удается записать данные в транспортное соединение: Программа на вашем хост-компьютере разорвала установленное подключение.
0
Эксперт .NETАвтор FAQ
 Аватар для Storm23
10428 / 5158 / 1825
Регистрация: 11.01.2015
Сообщений: 6,226
Записей в блоге: 34
04.06.2017, 20:05
Цитата Сообщение от wwworking Посмотреть сообщение
сделал в одном блоке. теперь выскакиевает:Не удается записать данные в транспортное соединение: Программа на вашем хост-компьютере разорвала установленное подключение.
потому что в вашем клиенте - точно такая же проблема: блок using для BinaryWriter закрывает поток, и поэтому сервер не может уже ничего отправить клиенту.
0
0 / 0 / 0
Регистрация: 31.05.2017
Сообщений: 33
04.06.2017, 20:29  [ТС]
Storm23, спасибо, исправил, помогло. а каким способом будет правильнее сделать? в одном блоке или с перегрузками:?
0
215 / 149 / 48
Регистрация: 28.12.2016
Сообщений: 716
05.06.2017, 00:57
Вы отправляете:
C#
1
2
   writer.Write(login);
                writer.Write(password);
Получаете:
C#
1
2
string login = reader.ReadString();
string password = reader.ReadString();
А что если кто-то бяку на сервер отправит, вам нужен класс для проверок.
К примеру просто
C#
1
   writer.Write("Сломать");
И на сервере будет вылет, ибо пароль мы не прочитаем.
Лучше пользуйтесь разделителем, к примеру :
Проверяйте сообщение от клиента по Regex или просто делите через Split и проверяйте, чтобы кол-во элементов в массиве к примеру равено 2 (логин и пароль)

C#
1
2
3
4
5
 var s = m.Split(':');
            if (s.Length != 2)
            {
                // ошибка формата.
            }
0
Эксперт .NET
 Аватар для Usaga
14815 / 9589 / 1368
Регистрация: 21.01.2016
Сообщений: 36,116
05.06.2017, 05:48
Цитата Сообщение от wwworking Посмотреть сообщение
а каким способом будет правильнее сделать? в одном блоке или с перегрузками:?
Правильны оба варианта. Разница только в том, какой из них вам подходит в данной ситуации.
0
0 / 0 / 0
Регистрация: 31.05.2017
Сообщений: 33
05.06.2017, 09:41  [ТС]
Usaga, вот что у меня вышло на данный момент
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Net.Sockets;
using System.Net;
 
namespace Server_Login
{
    class Package
    {
        public Package(string Login, string Password)
        {
            this.Login = Login;
            this.Password = Password;
        }
        public string Login { get; private set; } //Логин
        public string Password { get; private set; } // Пароль
    }
}
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
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Net.Sockets;
using System.Net;
using MySql.Data.MySqlClient;
 
namespace Server_Login
{
    class ClientObject
    {
        public TcpClient Client;
        public ClientObject(TcpClient tcpClient) { Client = tcpClient; }
        public void HandlerClient()
        {
            NetworkStream Stream = null;
            try
            {
                Stream = Client.GetStream();
                using (var reader = new BinaryReader(Stream))
                using (var writer = new BinaryWriter(Stream))
                {
                    // считываем данные из потока
                    string login = reader.ReadString();
                    string password = reader.ReadString();
 
                    // создаем по полученным данным объект пакета
                    Package package = new Package(login, password);
 
                    // обрабатываем полученные данные от клиента
                    Console.WriteLine("подключение клиента: {0}, пароль: {1}", package.Login, package.Password);
 
                    MySqlCommand command = new MySqlCommand(); ;
                    // строка подключения к БД
                    string connectString = "server=localhost;user=admin;database=mytestdb;password=1234;";
                    // создаём объект для подключения к БД
                    MySqlConnection connection = new MySqlConnection(connectString);
                    //создаем параметризированный запрос
                    string commandString = "SELECT * FROM account WHERE Login = "" + package.Login + "" AND Password = "" + package.Password + """;
                    command.CommandText = commandString;
                    command.Connection = connection;
                    MySqlDataReader read;
 
                    // устанавливаем соединение с БД
                    command.Connection.Open();
                    read = command.ExecuteReader();
                    //есть такой пользователь или нет, определяем по переменой result
                    bool resault = false;
                    if (read.Read())
                    {
                        resault = true;
                    }
                    read.Close();
                    // отправляем ответ клиенту
                    string Message = "";
                    if (resault == true)
                    {
                        Message = "server ok";
                    }
                    else
                    {
                        Message = "server no";
                    }
 
                    writer.Write(Message);
                    writer.Flush();
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
 
            finally
            {
                if (Stream != null) Stream.Close();
                if (Client != null) Client.Close();
            }
        }
    }
}
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
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Net.Sockets;
using System.Net;
 
namespace Server_Login
{
    class Program
    {
        const int Port = 5006;
        static void Main(string[] args)
        {
            TcpListener server = null;
            try
            {
                server = new TcpListener(IPAddress.Parse("127.0.0.1"), Port);
                server.Start();
 
                Console.WriteLine("Ожидание подключений...");
 
                while (true)
                {
                    TcpClient tcpClient = server.AcceptTcpClient();
                    ClientObject client = new ClientObject(tcpClient);
 
                    var task = Task.Run(() => { client.HandlerClient(); });
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            finally
            {
                if (server != null) server.Stop();
            }
        }
    }
}
и вот код клиента на юнити
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
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using System.Net;
using System.Net.Sockets;
using System.Text;
using UnityEngine.SceneManagement;
using System;
using System.IO;
public class ScriptLoad01 : MonoBehaviour 
{
    public InputField InputBox1;
    public InputField InputBox2;
    public GameObject ErrorPanel;
 
    const int PORT = 5006;
    const string ADDRESS = "127.0.0.1";
    public void OnClick()
    {
        string log = InputBox1.text;
        string pas = InputBox2.text;
 
        TcpClient tcpClient = null;
 
        try
        {
            string login = log;
            string password = pas;
 
            tcpClient = new TcpClient(ADDRESS, PORT);
 
            NetworkStream stream = tcpClient.GetStream();
 
            using (var writer = new BinaryWriter(stream))
            using (var reader = new BinaryReader(stream))
            {
                writer.Write(login);
                writer.Write(password);
                writer.Flush();
      
                string Message = reader.ReadString();
 
                if (Message == "server ok")
                {
                    SceneManager.LoadScene(1);
                }
                else
                {
                    ErrorPanel.SetActive(true);
                    Debug.Log("Неправильный логин или пароль");
                }
            }
        }
        catch(Exception ex)
        {
            Debug.Log(ex.Message);
        }
        finally
        {
            tcpClient.Close();
        }
    }
}
0
Эксперт .NETАвтор FAQ
 Аватар для Storm23
10428 / 5158 / 1825
Регистрация: 11.01.2015
Сообщений: 6,226
Записей в блоге: 34
05.06.2017, 09:44
wwworking, Defences,
Отправлять пароль в открытом виде вообще нельзя. Такая система элементарно взламывается.

Самая простая допустимая система авторизации такова:
1) На стороне клиента пользователь вводит логин и пароль.
2) С сервера запрашивается случайное число (сам сервер это число запоминает).
3) Число и пароль складываются в одну строку и для нее считается хеш каким либо алгоритмом (например md5).
4) Серверу отправляется логин и вычисленный хеш.
5) Сервер принимает логин/хеш, по логину ищет пароль в своей базе данных, складывает с числом, считает хеш таким же алгоритмом как и клиент.
6) Если хеш совпал, генерируется номер сессии (с ограниченным сроком действия). Номер сессии отправляется клиенту.
7) Далее клиент отправляет запросы на сервер указывая только номер сессии. Логин и хеш более не передаются (до тех пор, пока не истечет время сессии).

Либо альтернативный вариант (чуть попроще):
1) Клиент отправляет все запросы в виде двух блоков - первый блок содержит логин(или номер сессии), второй блок - содержит данные. Блок данных шифруется с использованием пароля в качестве ключа.
2) Сервер принимает блок логина, по своей базе находит пароль, и расшифровывает второй блок, используя пароль как ключ.

wwworking,
И кстати, почему вы решили использовать TCP? В играх обычно нужна малая латентность, а это достигается в UDP.
1
0 / 0 / 0
Регистрация: 31.05.2017
Сообщений: 33
05.06.2017, 09:56  [ТС]
Storm23, чет все сложно у вас =) придется серьёзно подумать как это провернуть, ну я хз, мне показалось что tcp будет оптимальнее =)
0
Эксперт .NET
 Аватар для Usaga
14815 / 9589 / 1368
Регистрация: 21.01.2016
Сообщений: 36,116
05.06.2017, 09:58
wwworking, мне так кажется, что вам ещё рановато за игрушку браться. Ой как рановато.
0
0 / 0 / 0
Регистрация: 31.05.2017
Сообщений: 33
05.06.2017, 09:59  [ТС]
Usaga, волков бояться - в лес не ходить =)
0
Эксперт .NETАвтор FAQ
 Аватар для Storm23
10428 / 5158 / 1825
Регистрация: 11.01.2015
Сообщений: 6,226
Записей в блоге: 34
05.06.2017, 10:14
wwworking,
Да и еще, если уж использовать TCP, то его нужно один раз открыть и держать открытым, не закрывая. При необходимости передачи данных - передавать в потоковом режиме через уже открытый сокет.
0
0 / 0 / 0
Регистрация: 31.05.2017
Сообщений: 33
05.06.2017, 16:05  [ТС]
Storm23, ну так у меня вроде как серверный сокет и не закрывается, лишь клиентские
0
Эксперт .NET
 Аватар для Usaga
14815 / 9589 / 1368
Регистрация: 21.01.2016
Сообщений: 36,116
05.06.2017, 16:58
wwworking, ну так соединение же вы разрываете))) Поддерживать соединение открытым можно ну очень долго, это практически бесплатно в плане ресурсов.
0
9993 / 2965 / 497
Регистрация: 05.10.2013
Сообщений: 8,150
Записей в блоге: 244
06.06.2017, 17:14
wwworking, может вам пригодится книга:Для примера в книге взят язык C++ и библиотека SDL2 - для сети, но книга не об этом.
0
0 / 0 / 0
Регистрация: 31.05.2017
Сообщений: 33
13.06.2017, 15:48  [ТС]
Usaga, tcpClient.Close(); в этой строчке получается я закрываю соединение?
0
Эксперт .NET
 Аватар для Usaga
14815 / 9589 / 1368
Регистрация: 21.01.2016
Сообщений: 36,116
13.06.2017, 15:57
wwworking, ага.
0
0 / 0 / 0
Регистрация: 31.05.2017
Сообщений: 33
14.06.2017, 14:29  [ТС]
Usaga, т.е. мне нужно убрать блок finnaly и тогда соединение с клиентом не будет разорвано со стороны сервера, и если клиент еще раз пошлет что-то на сервер то мы не будем по новой подключаться а будем уже работать с открытым подключением и в выделенным нам потоке?
0
Эксперт .NET
 Аватар для Usaga
14815 / 9589 / 1368
Регистрация: 21.01.2016
Сообщений: 36,116
14.06.2017, 14:37
wwworking, сокет нужно "запомнить" где-нибудь во внутренней коллекции на сервере (если о нём речь) и обслуживать обмен данными через него в отдельном потоке до тех пор, пока или сервер или клиент не решат разъедениться.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
14.06.2017, 14:37

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

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

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

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

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


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

Или воспользуйтесь поиском по форуму:
80
Ответ Создать тему
Новые блоги и статьи
Программное добавление префикса в нумерацию документов
Maks 27.10.2026
Реализация из решения ниже выполнена в самописной конфигурации на БСП (помощь начинающему коллеге). Задача: Программно добавить префикс в нумерацию документов. Решение: В модуле объекта. . .
После закрытия оутлука продолжает висеть процесс в диспетчере задач
Maks 27.10.2026
С недавнего времени в продакшене возникла проблема: при закрытии оутлука в диспетчере задач продолжал висеть процесс outlook. exe. Проблема возникла после установки MS Office 2021 LTSC на машинах, под. . .
Baragoz - DPS/HPS бот для WoW 3.3.5a, многоязычный
AmbA 26.10.2026
Хотите ещё ботов? У меня есть один! А я пока отдохну от него. https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=12062&stc=1&d=1793007952 Инструкция внутри. https:/ / youtu. be/ VpfFZSUDGnQ. . .
Особенности gif сгенерированных в Си
russiannick 21.10.2026
Рассмотрим генерацию gif файлов, которые в Си имеют свои особенности. Gif представляет собой графический формат популярный в интернете. Посмотрим на палитру. Gif файл сгенерированный в си отличается. . .
FPS контроллер с анимированными Y-Bot и 3D-звуком miniaudio (Box3D, Recast, BehaviorTree.CPP, ozz-animation, ImGui, OpenGL и SDL3)
8Observer8 18.10.2026
Содержание блога | English Version Полное мультиплатформенное руководство по стартовому проекту с FPS-контроллером игрока, анимированными роботами Y-Bot с 4-слойным блендингом, 3D-физикой Box3D,. . .
Локальный http сервер
Argus19 17.10.2026
Локальный http сервер На работе, на двух локальных компьютерах круглосуточно работают программы опроса приборов с записью в книги Excel,которые раз в сутки записываются на сервер компании. Т. к. . . .
Копировать Windows на новый диск на UEFI
damix 17.10.2026
https:/ / uriesk. wordpress. com/ 2016/ 11/ 01/ move-window-10-to-ssd-on-a-uefi-dualboot-system-with-basic-linux-tools/ TL DR Вставляем диск, а старый подключаем через переходник, грузимся с лайва. . .
ИИ не может найти нужный язык в списке
Supersumestria 05.10.2026
Я ему даю вот такое изображение и прошу найти и подчеркнуть немецкий язык. Возвращает он вот это: https:/ / i. **********/ vqBWLe2. png Нужную строчку в 3й колонке просто выдумал. . Это. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru