В массив выводить данные-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;
- }
- }
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д