Асинхронные клиент-сервер,Виндовс форма и БД, пишу не совсем простую онлайн игру - 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);
}
}