В массив выводить данные-id клиента, данные серверу и данные, отправленные сервером - C#
Формулировка задачи:
Здравствуйте. Имеется клиент-серверное приложение, вопрос по стороне сервера.
Имеется backgroundworker-bw_clientReceining:
и есть класс handleClient:
Принимаем новых клиентов в классе:
так же в классе есть функция общения doChat()-её код опустим
Задача заключается вот в чём:
Хочу в массив выводить данные-ид клиента, данные серверу и данные отправленные сервером.
Смотрите, когда я завожу нового клиента, он в функцию startClient(TcpClient inClientSocket, string clientNO)-передаёт clientNO-то есть я думал это использовать в качестве идентификатора строки массива.
Единственное решение, которое пришло в голову, это создать ещё один backgroundworker-bw_statusUp и в нём бесконечный цикл сделать, где мы будем получать свойство нашего класса. В класс handleClient добавил свойства:
Но я не учёл того, что в backgroundworker-bw_statusUp нет возможножности дотянуться до класса handleClient, так как он в другом backgroundworker потоке создан.
Вопросы:
1. Правильно ли я думаю про то, как вытаскивать данные из потока, или есть какой-то более правильный способ. Если есть способ, подскажите его, а если нет, то подскажите, как дотянуться из потока backgroundworker-bw_statusUp до данных класса в потоке backgroundworker-bw_clientReceining.
2. В случае отключения клиента, как мы отключаем клиента Верно?
А как нам остановить именно тот поток, от которого отключился клиент. Не понимаю.
Уважаемые, очень надеюсь на Вашу помощь. Спасибо.
TcpListener serverSocket = new TcpListener(8888);
TcpClient clietnSocket = default(TcpClient);
serverSocket.Start();
bw_clientReceining.ReportProgress(1);
while (true | !bw_clientReceining.CancellationPending)
{
counterClient++;
clietnSocket = serverSocket.AcceptTcpClient();
bw_clientReceining.ReportProgress(2);
handleClient client = new handleClient();
client.startClient(clietnSocket, Convert.ToString(counterClient));
Thread.Sleep(5000);
DataClientToServerID.Add("");
DataClientToServerStatus.Add("");
DataServerTOClientStatus.Add("");
}
clietnSocket.Close();
serverSocket.Stop();public void startClient(TcpClient inClientSocket, string clientNO)
{
this.clientSocket = inClientSocket;
clientNO = clientNO;
Thread ctThread = new Thread(doChat);
ctThread.Start();
}public int ClientNo
{
get
{
return clientNO;
}
}
public string ClientID
{
get
{
return clID;
}
}clientSocket.Close();
Решение задачи: «В массив выводить данные-id клиента, данные серверу и данные, отправленные сервером»
textual
Листинг программы
class Server : BackgroundWorker
{
private TcpListener listener;
private List<Connection> connections;
private bool exit;
public Server(int port)
{
listener = new TcpListener(IPAddress.Any, port);
listener.Start();
}
private void Message(string message)
{
Console.Write(DateTime.Now.ToLongTimeString() + ": " + message);
}
public void Broadcast(string message)
{
for (int i = 0; i < connections.Count; i++)
{
if (connections[i].currentState == Connection.State.Authorized)
connections[i].Write(message);
}
}
protected override void OnDoWork(DoWorkEventArgs e)
{
Message("Сервер стартовал\n");
while (true)
{
Thread.Sleep(1);
if (exit) return;
try
{
if (listener.Pending())
{
TcpClient client = listener.AcceptTcpClient();
Message("Подключился клиент: " + client.Client.RemoteEndPoint.ToString() + "\n");
Connection c = new Connection(client, this);
connections.Add(c);
c.onBroadcast += new EventHandler<ObjectEventArgs>(c_onBroadcast);
c.onClose += new EventHandler<ObjectEventArgs>(c_onClose);
}
}
catch (Exception err)
{
Message("Сервер сообщает об ошибке: " + err.Message + "\n");
continue;
}
}
}
void c_onClose(object sender, ObjectEventArgs e)
{
Connection c = sender as Connection;
c.Exit();
connections.Remove(c);
}
void c_onBroadcast(object sender, ObjectEventArgs e)
{
Broadcast(e.value.ToString());
}
public void Exit()
{
exit = true;
}
}
class Connection
{
public enum State
{
WaitForLogin = 0,
WaitForPassword = 1,
Authorized = 2
}
public State currentState { get; private set; }
private Server server;
private TcpClient client;
private NetworkStream stream;
private Thread communicatingThread;
private Random rnd;
private byte[] sessionID;
private string ip;
private string port;
private int wrongPasswordsAttempt;
private bool exit;
public event EventHandler<ObjectEventArgs> onBroadcast = delegate { };
public event EventHandler<ObjectEventArgs> onClose = delegate { };
public Connection(TcpClient client, Server server)
{
currentState = State.WaitForLogin;
this.server = server;
this.client = client;
ip = ((IPEndPoint)client.Client.RemoteEndPoint).Address.ToString();
port = ((IPEndPoint)client.Client.RemoteEndPoint).Port.ToString();
stream = client.GetStream();
communicatingThread = new Thread(new ThreadStart(Communicating));
communicatingThread.IsBackground = true;
communicatingThread.Start();
rnd = new Random();
}
private void Message(string message)
{
Console.Write(DateTime.Now.ToLongTimeString() + ": " + message);
}
private void Communicating()
{
string input = String.Empty;
byte[] message = new byte[0];
Message("Поток соединения " + ip + ":" + port + " стартовал\n");
while (true)
{
if (exit) break;
Thread.Sleep(1);
try
{
if (stream.CanRead)
{
message = new byte[0];
if (stream.DataAvailable)
{
byte[] buffer = new byte[65535];
using (MemoryStream messageStream = new MemoryStream())
{
while (stream.DataAvailable)
{
int bytesRead = stream.Read(buffer, 0, buffer.Length);
messageStream.Write(buffer, 0, bytesRead);
}
message = messageStream.ToArray();
}
}
if (message.Length > 0)
{
switch (currentState)
{
case State.WaitForLogin:
input = Encoding.UTF8.GetString(message);
CheckLogin(input);
break;
case State.WaitForPassword:
CheckPassword(message);
break;
case State.Authorized:
input = Encoding.UTF8.GetString(message);
Message(String.Format("[{0} {1}:{2}]: {3}\n", currentAccount.Login, ip, port, input));
onBroadcast(this, new ObjectEventArgs(String.Format("[{0}]: {1}\n", currentAccount.Login, input)));
break;
default:
throw new Exception(String.Format("Соединение оказалось в неизвестном состоянии и будет закрыто\n"));
}
}
}
if (client.Client.Poll(0, SelectMode.SelectRead))
{
byte[] checkConn = new byte[1];
if (client.Client.Receive(checkConn, SocketFlags.Peek) == 0)
{
Message("Клиент " + ip + ":" + port + " отключился\n");
break;
}
}
}
catch (Exception err)
{
Message(String.Format("Соединение {0}:{1} сообщает об ошибке:{2}\n", ip, port, err.Message));
break;
}
}
Message("Соединение " + ip + ":" + port + " закрывается\n");
stream.Close();
client.Close();
Message("Поток соединения " + ip + ":" + port + " завершился\n");
onClose(this, null);
}
public void Write(string message)
{
try
{
byte[] bytes = Encoding.UTF8.GetBytes(message);
stream.Write(bytes, 0, bytes.Length);
}
catch (IOException) { return; }
}
public void Write(byte[] buffer)
{
try
{
stream.Write(buffer, 0, buffer.Length);
}
catch (IOException) { return; }
}
public void Exit()
{
exit = true;
}
}
class ObjectEventArgs : EventArgs
{
public object value { get; private set; }
public ObjectEventArgs(object arg)
{
value = arg;
}
}