Асинхронные клиент-сервер,Виндовс форма и БД, пишу не совсем простую онлайн игру - C#

Узнай цену своей работы

Формулировка задачи:

Доброго времени суток господа программисты. Начну с того, что сам не учился на программиста в своё время, тогда просто ещё не было этого =). Теперь сам потихоньку осваиваю программирование. Начал с языка ботов Autoit, не плохо получалось с написанием скриптов для ботов онлайн игр. Но для полноценного написания кода онлайн игрушки Autoit конечно же не подходит, тогда остановился на C#. Создал эту тему на форуме, с надеждой, что есть не мало людей которым будет интересно не только просматривать тему ради любопытства и примеров кода в этой теме, но и самим решать множество задач разной сложности, которые тут будут литься рекой =). В общем с Windows Form я уже более-менее познакомился и могу кое что писать с помощью VS2010. Сейчас задачка стоит в том, что бы подружить асинхронный клиент и сервер с формой, проще говоря из консольного приложения переделать в Windows Form. Сразу могу сказать, что в теме клиент-сервер я совсем новичок =(. На просторах интернета нашёл примеры кода асинхронных клиент-сервер. клиент:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.Net;
 
namespace TestSocketAsyncClient
{
    class Client
    {
        private Socket Sock;
        private SocketAsyncEventArgs SockAsyncArgs;
        private byte[] buff;
 
        //В конструкторе они будут инициализироваться:
        public Client()
        {
            buff = new byte[1024];
            Sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            SockAsyncArgs = new SocketAsyncEventArgs();
            SockAsyncArgs.Completed += SockAsyncArgs_Completed;
        }
 
        //Для соединения с сервером служит метод ConnectAsync,
        //которому передается адрес и порт для соединения с сервером:
        public void ConnectAsync(string Address, int Port)
        {
            SockAsyncArgs.RemoteEndPoint = new DnsEndPoint(Address, Port);
            ConnectAsync(SockAsyncArgs);
        }
        private void ConnectAsync(SocketAsyncEventArgs e)
        {
            bool willRaiseEvent = Sock.ConnectAsync(e);
            if (!willRaiseEvent)
                ProcessConnect(e);
        }
 
        //После того, как соединение установлено, можно и посылать данные. Для этого служит 
        //функция SendAsync. Организация этой функции похожа на ConnectAsync:
        public void SendAsync(string data)
        {
            if (Sock.Connected && data.Length > 0)
            {
                byte[] buff = Encoding.UTF8.GetBytes(data);
                SocketAsyncEventArgs e = new SocketAsyncEventArgs();
                e.SetBuffer(buff, 0, buff.Length);
                e.Completed += SockAsyncArgs_Completed;
                SendAsync(e);
            }
        }
        private void SendAsync(SocketAsyncEventArgs e)
        {
            bool willRaiseEvent = Sock.SendAsync(e);
            if (!willRaiseEvent)
                ProcessSend(e);
        }
 
        private void ReceiveAsync(SocketAsyncEventArgs e)
        {
            bool willRaiseEvent = Sock.ReceiveAsync(e);
            if (!willRaiseEvent)
                ProcessReceive(e);
        }
        // Функция SockAsyncArgs_Completed просто вызывает соответствующую функцию Process* 
        // после завершения какой-либо операции:
        void SockAsyncArgs_Completed(object sender, SocketAsyncEventArgs e)
        {
            switch (e.LastOperation)
            {
                case SocketAsyncOperation.Connect:
                    ProcessConnect(e);
                    break;
                case SocketAsyncOperation.Receive:
                    ProcessReceive(e);
                    break;
                case SocketAsyncOperation.Send:
                    ProcessSend(e);
                    break;
            }
        }
 
        //После того, как отправили данные, надо бы прочитать ответ. Поэтому в ProcessSend мы вызываем
        //функцию ReceiveAsync, которая обеспечит прием данных:
        private void ProcessSend(SocketAsyncEventArgs e)
        {
            if (e.SocketError == SocketError.Success)
            {
                ReceiveAsync(SockAsyncArgs);
            }
            else
            {
                Console.WriteLine("Dont send");
            }
        }
 
        //А в функции ProcessReceive мы просто выводим на экран то что приняли:
       private void ProcessReceive(SocketAsyncEventArgs e)
        {
            if (e.SocketError == SocketError.Success)
            {
                string str = Encoding.UTF8.GetString(e.Buffer, 0, e.BytesTransferred);
                Console.WriteLine("Receive: {0}", str);
            }
            else
            {
                Console.WriteLine("Dont recieve");
            }
        }
 
        //А в ProcessConnect мы просто проверяем, были ли ошибки, и, если их не было, 
        //устанавливаем буфер и выводим сообщение о том, что соединение успешно:
        private void ProcessConnect(SocketAsyncEventArgs e)
        {
            if (e.SocketError == SocketError.Success)
            {
                Console.WriteLine("Connected to {0}...", e.RemoteEndPoint.ToString());
                SockAsyncArgs.SetBuffer(buff, 0, buff.Length);
            }
            else
            {
                Console.WriteLine("Dont connect to {0}", e.RemoteEndPoint.ToString());
            }
        }
    }
}
сервер:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;
 
namespace TestSocketAsyncServer
{
    class Server
    {
        private Socket Sock;
        private SocketAsyncEventArgs AcceptAsyncArgs;
 
        public Server()
        {
            Sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            AcceptAsyncArgs = new SocketAsyncEventArgs();
            AcceptAsyncArgs.Completed += AcceptCompleted;
        }
 
        private void AcceptCompleted(object sender, SocketAsyncEventArgs e)
        {
            if (e.SocketError == SocketError.Success)
            {
                ClientConnection Client = new ClientConnection(e.AcceptSocket);
            }
            e.AcceptSocket = null;
            AcceptAsync(AcceptAsyncArgs);
        }
        private void AcceptAsync(SocketAsyncEventArgs e)
        {
            bool willRaiseEvent = Sock.AcceptAsync(e);
            if (!willRaiseEvent)
                AcceptCompleted(Sock, e);
        }
 
        public void Start(int Port)
        {
            Sock.Bind(new IPEndPoint(IPAddress.Any,Port));
            Sock.Listen(50);
            AcceptAsync(AcceptAsyncArgs);
        }
        public void Stop()
        {
            Sock.Close();
        }
 
    }
}
class ClientConnection
    {
        private static int ClientNumber = 0;
 
        private Socket Sock;
        private SocketAsyncEventArgs SockAsyncEventArgs;
        private byte[] buff;
 
        public ClientConnection(Socket AcceptedSocket)
        {
            ClientNumber++;
            buff = new byte[1024];
            Sock = AcceptedSocket;
            SockAsyncEventArgs = new SocketAsyncEventArgs();
            SockAsyncEventArgs.Completed += SockAsyncEventArgs_Completed;
            SockAsyncEventArgs.SetBuffer(buff, 0, buff.Length);
 
            ReceiveAsync(SockAsyncEventArgs);
        }
 
        private void SockAsyncEventArgs_Completed(object sender, SocketAsyncEventArgs e)
        {
            switch (e.LastOperation)
            {
                case SocketAsyncOperation.Receive:
                    ProcessReceive(e);
                    break;
                case SocketAsyncOperation.Send:
                    ProcessSend(e);
                    break;
            }
        }
 
        private void ProcessSend(SocketAsyncEventArgs e)
        {
            if(e.SocketError == SocketError.Success)
                ReceiveAsync(SockAsyncEventArgs);
        }
 
        private void ProcessReceive(SocketAsyncEventArgs e)
        {
            if (e.SocketError == SocketError.Success)
            {
                string str = Encoding.UTF8.GetString(e.Buffer, 0, e.BytesTransferred);
                Console.WriteLine("Incoming msg from #{0}: {1}", ClientNumber, str);
                SendAsync("You send " + str);
            }
        }
 
        private void ReceiveAsync(SocketAsyncEventArgs e)
        {
            bool willRaiseEvent = Sock.ReceiveAsync(e);
            if (!willRaiseEvent)
                ProcessReceive(e);
        }
        private void SendAsync(string data)
        {
            byte [] buff = Encoding.UTF8.GetBytes(data);
            SocketAsyncEventArgs e = new SocketAsyncEventArgs();
            e.Completed += SockAsyncEventArgs_Completed;
            e.SetBuffer(buff, 0, buff.Length);
            SendAsync(e);
        }  
        private void SendAsync(SocketAsyncEventArgs e)
        {
            bool willRaiseEvent = Sock.SendAsync(e);
            if (!willRaiseEvent)
                ProcessSend(e);
        }

    }
}
и прмерно такая форма клиента:
   #endregion
 
        private System.Windows.Forms.Button button1;      // Подключиться к серверу(Connected)
        private System.Windows.Forms.Button button2;      // Отправить сообщение(Send)
        private System.Windows.Forms.TextBox txtLog;      // Вывод символов в окно формы(Log)
        private System.Windows.Forms.TextBox txtIp;        // Поле для ввода символов адреса сервера(IP)
        private System.Windows.Forms.TextBox txtUser;     // Поле для ввода символов имя клиента(Nickname)
        private System.Windows.Forms.TextBox txtpassword1;//Поле для ввода пароля(password1)
        private System.Windows.Forms.TextBox txtpassword2;//Поле для ввода пароля(password2)
        private System.Windows.Forms.TextBox txtMessage;// Поле для ввода символов сообщения   
        private System.Windows.Forms.Label Nickname;         //
        private System.Windows.Forms.Label IPServer;           //
        private System.Windows.Forms.Label password1;           //
        private System.Windows.Forms.Label password2;           //
форма сервера :
   #endregion
 
        private System.Windows.Forms.Button button1;      // Начать прослушивать порт        
        private System.Windows.Forms.TextBox txtLog;      // Вывод символов в окно формы(Log)
        private System.Windows.Forms.TextBox txtIp;        // Поле для ввода символов адреса сервера(IP)       
        private System.Windows.Forms.Label IPServer;           //
На форме клиента 2 кнопки - "Подключиться" и "Отправить", при подключении надо чтобы кнопка "Подключиться" превращалась в "Отключиться". 3 TextBox для регистрации и авторизации клиента(позже надо будет сделать БД). 2 TextBox для ввода и вывода символов. Форма сервера - TextBox для IP сервера, TextBox для вывода символов(Log) и кнопка для запуска сервера. Я пока не могу соединить форму с кодом клиента или сервера, точнее вставить то в форму код вставил, но как переделать вывод символов из консоли в TextBox не знаю. так не работает:
 //А в ProcessConnect мы просто проверяем, были ли ошибки, и, если их не было, 
            //устанавливаем буфер и выводим сообщение о том, что соединение успешно:
            private void ProcessConnect(SocketAsyncEventArgs e)
            {
                if (e.SocketError == SocketError.Success)
                {
                    //   Console.WriteLine
                    txtLog.Text += "Connected to {0}..." + e.RemoteEndPoint.ToString();
                    SockAsyncArgs.SetBuffer(buff, 0, buff.Length);
 
                }
                else
                {
                    //  Console.WriteLine
                    txtLog.Text += "Dont connect to {0}" + e.RemoteEndPoint.ToString();
 
                }
            }
Прошу сильно не ругаться и плевать, так как я совсем новичок в этом деле, а просто помочь примерами кода (с подробными комментариями). И возможно у кого то будет время прокомментировать подробнее примеры клиента и сервера выше? Подробные комментарии в коде помогут многим новичкам. Осваивать язык на примерах с пояснениями гораздо удобнее и быстрее. А таких примеров очень-очень мало, я имею ввиду с подробными комментариями к каждой строке кода на русском языке. Ну для начала пока достаточно, как осилим эту задачку, тогда продолжим написание игры дальше =).

Решение задачи: «Асинхронные клиент-сервер,Виндовс форма и БД, пишу не совсем простую онлайн игру»

textual
Листинг программы
 private void btnConnect_Click(object sender, EventArgs e)
        {
 
            ClientS();
            ConnectAsync("127.0.0.1", 4505);
 
            while (true)
             
            {
                string data = txtMessage.Text;
                SendAsync(data);
            }
        }

ИИ поможет Вам:


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

Оцени полезность:

9   голосов , оценка 3.889 из 5
Похожие ответы