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