Асинхронные клиент-сервер,Виндовс форма и БД, пишу не совсем простую онлайн игру - C#
Формулировка задачи:
Доброго времени суток господа программисты.
Начну с того, что сам не учился на программиста в своё время, тогда просто ещё не было этого =).
Теперь сам потихоньку осваиваю программирование. Начал с языка ботов Autoit, не плохо получалось с написанием скриптов для ботов онлайн игр. Но для полноценного написания кода онлайн игрушки Autoit конечно же не подходит,
тогда остановился на C#.
Создал эту тему на форуме, с надеждой, что есть не мало людей которым будет интересно не только просматривать тему
ради любопытства и примеров кода в этой теме, но и самим решать множество задач разной сложности, которые тут
будут литься рекой =).
В общем с Windows Form я уже более-менее познакомился и могу кое что писать с помощью VS2010.
Сейчас задачка стоит в том, что бы подружить асинхронный клиент и сервер с формой, проще говоря из консольного
приложения переделать в Windows Form. Сразу могу сказать, что в теме клиент-сервер я совсем новичок =(.
На просторах интернета нашёл примеры кода асинхронных клиент-сервер.
клиент:
сервер:
и прмерно такая форма клиента:
форма сервера :
На форме клиента 2 кнопки - "Подключиться" и "Отправить", при подключении надо чтобы кнопка "Подключиться"
превращалась в "Отключиться".
3 TextBox для регистрации и авторизации клиента(позже надо будет сделать БД).
2 TextBox для ввода и вывода символов.
Форма сервера - TextBox для IP сервера, TextBox для вывода символов(Log) и кнопка для запуска сервера.
Я пока не могу соединить форму с кодом клиента или сервера, точнее вставить то в форму код вставил, но как переделать
вывод символов из консоли в TextBox не знаю.
так не работает:
Прошу сильно не ругаться и плевать, так как я совсем новичок в этом деле, а просто помочь примерами кода (с подробными комментариями).
И возможно у кого то будет время прокомментировать подробнее примеры клиента и сервера выше?
Подробные комментарии в коде помогут многим новичкам. Осваивать язык на примерах с пояснениями
гораздо удобнее и быстрее. А таких примеров очень-очень мало, я имею ввиду с подробными комментариями к каждой строке кода на русском языке.
Ну для начала пока достаточно, как осилим эту задачку, тогда продолжим написание игры дальше =).
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; //
//А в 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); } }
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д