В массив выводить данные-id клиента, данные серверу и данные, отправленные сервером - C#

Узнай цену своей работы

Формулировка задачи:

Здравствуйте. Имеется клиент-серверное приложение, вопрос по стороне сервера. Имеется backgroundworker-bw_clientReceining:
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();
и есть класс handleClient: Принимаем новых клиентов в классе:
public void startClient(TcpClient inClientSocket, string clientNO)
        {
            this.clientSocket = inClientSocket;
            clientNO = clientNO;
            Thread ctThread = new Thread(doChat);
            ctThread.Start();
        }
так же в классе есть функция общения doChat()-её код опустим Задача заключается вот в чём: Хочу в массив выводить данные-ид клиента, данные серверу и данные отправленные сервером. Смотрите, когда я завожу нового клиента, он в функцию startClient(TcpClient inClientSocket, string clientNO)-передаёт clientNO-то есть я думал это использовать в качестве идентификатора строки массива. Единственное решение, которое пришло в голову, это создать ещё один backgroundworker-bw_statusUp и в нём бесконечный цикл сделать, где мы будем получать свойство нашего класса. В класс handleClient добавил свойства:
public int ClientNo
        {
            get
            {
                return clientNO;
            }
        }
        public string ClientID
        {
            get
            {
                return clID;
            }
        }
Но я не учёл того, что в backgroundworker-bw_statusUp нет возможножности дотянуться до класса handleClient, так как он в другом backgroundworker потоке создан. Вопросы: 1. Правильно ли я думаю про то, как вытаскивать данные из потока, или есть какой-то более правильный способ. Если есть способ, подскажите его, а если нет, то подскажите, как дотянуться из потока backgroundworker-bw_statusUp до данных класса в потоке backgroundworker-bw_clientReceining. 2. В случае отключения клиента, как мы отключаем клиента
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;
        }
    }

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

12   голосов , оценка 4.083 из 5
Похожие ответы