Member 13188172 Ответов: 0

Tcp клиент-сервер c# чат-приложение


Я создал клиент-серверное приложение, использующее сетевой поток для отправки и получения сообщений, но всякий раз, когда я отправляю сообщение с помощью клиента, сервер отправляет сообщение обратно этому клиенту, но я хочу отправить это сообщение дальше какому-то другому клиенту.

т.е.

что происходит:
Клиент a - - - - - - & gt; сервер
сервер - - - - - - & gt; клиент a

что нужно сделать:
клиент a - - - - - - - & gt; сервер
сервер - - - - - - - & gt; клиент b

код сервера приведен ниже

Что я уже пробовал:

using System;
using System.Collections.Generic;
using System.Text;


using System;
using System.IO;
using System.Net.Sockets;
using System.Text;
using System.Collections;
using System.Threading;

namespace TcpServer3
{


    class ClientConnectionPool
    {
        // Creates a synchronized wrapper around the Queue.
        private Queue SyncdQ = Queue.Synchronized(new Queue());

        public void Enqueue(ClientHandler client)
        {
            SyncdQ.Enqueue(client);
        }

        public ClientHandler Dequeue()
        {
            return (ClientHandler)(SyncdQ.Dequeue());
        }

        public int Count
        {
            get { return SyncdQ.Count; }
        }

        public object SyncRoot
        {
            get { return SyncdQ.SyncRoot; }
        }

    } // class ClientConnectionPool

    class ClientService
    {

        const int NUM_OF_THREAD = 10;

        private ClientConnectionPool ConnectionPool;
        private bool ContinueProcess = false;
        private Thread[] ThreadTask = new Thread[NUM_OF_THREAD];

        public ClientService(ClientConnectionPool ConnectionPool)
        {
            this.ConnectionPool = ConnectionPool;
        }

        public void Start()
        {
            ContinueProcess = true;
            // Start threads to handle Client Task
            for (int i = 0; i < ThreadTask.Length; i++)
            {
                ThreadTask[i] = new Thread(new ThreadStart(this.Process));
                ThreadTask[i].Start();
            }
        }

        private void Process()
        {
            while (ContinueProcess)
            {

                ClientHandler client = null;
                lock (ConnectionPool.SyncRoot)
                {
                    if (ConnectionPool.Count > 0)
                        client = ConnectionPool.Dequeue();
                }
                if (client != null)
                {
                    client.Process(); // Provoke client
                    // if client still connect, schedufor later processingle it 
                    if (client.Alive)
                        ConnectionPool.Enqueue(client);
                }

                Thread.Sleep(100);
            }
        }

        public void Stop()
        {
            ContinueProcess = false;
            for (int i = 0; i < ThreadTask.Length; i++)
            {
                if (ThreadTask[i] != null && ThreadTask[i].IsAlive)
                    ThreadTask[i].Join();
            }

            // Close all client connections
            while (ConnectionPool.Count > 0)
            {
                ClientHandler client = ConnectionPool.Dequeue();
                client.Close();
                Console.WriteLine("Client connection is closed!");
            }
        }

    } // class ClientService


    public class SynchronousSocketListener
    {

        private const int portNum = 3020;

        public static void StartListening()
        {

            ClientService ClientTask;

            // Client Connections Pool
            ClientConnectionPool ConnectionPool = new ClientConnectionPool();

            // Client Task to handle client requests
            ClientTask = new ClientService(ConnectionPool);

            ClientTask.Start();

            TcpListener listener = new TcpListener(portNum);
            try
            {
                listener.Start();

                int TestingCycle = 3; // Number of testing cycles
                int ClientNbr = 0;

                // Start listening for connections.
                Console.WriteLine("Waiting for a connection...");
                while (TestingCycle > 0)
                {

                    TcpClient handler = listener.AcceptTcpClient();

                    if (handler != null)
                    {
                        Console.WriteLine("Client#{0} accepted!", ++ClientNbr);

                        // An incoming connection needs to be processed.
                        ConnectionPool.Enqueue(new ClientHandler(handler));

                        --TestingCycle;
                    }
                    else
                        break;
                }
                listener.Stop();

                // Stop client requests handling
                ClientTask.Stop();


            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
            }

            Console.WriteLine("\nHit enter to continue...");
            Console.Read();
        }


        public static int Main(String[] args)
        {
            StartListening();
            return 0;
        }
    }



    class ClientHandler
    {

        private TcpClient ClientSocket;
        private NetworkStream networkStream;
        bool ContinueProcess = false;
        private byte[] bytes; 		// Data buffer for incoming data.
        private StringBuilder sb = new StringBuilder(); // Received data string.
        private string data = null; // Incoming data from the client.

        public ClientHandler(TcpClient ClientSocket)
        {
            ClientSocket.ReceiveTimeout = 100; // 100 miliseconds
            this.ClientSocket = ClientSocket;
            networkStream = ClientSocket.GetStream();
            bytes = new byte[ClientSocket.ReceiveBufferSize];
            ContinueProcess = true;
        }

        public void Process()
        {

            try
            {
                int BytesRead = networkStream.Read(bytes, 0, (int)bytes.Length);
                if (BytesRead > 0)
                    // There might be more data, so store the data received so far.
                    sb.Append(Encoding.ASCII.GetString(bytes, 0, BytesRead));
                else
                    // All the data has arrived; put it in response.
                    ProcessDataReceived();

            }
            catch (IOException)
            {
                // All the data has arrived; put it in response.
                ProcessDataReceived();
            }
            catch (SocketException)
            {
                networkStream.Close();
                ClientSocket.Close();
                ContinueProcess = false;
                Console.WriteLine("Conection is broken!");
            }

        }  // Process()

        private void ProcessDataReceived()
        {
            if (sb.Length > 0)
            {
                bool bQuit = (String.Compare(sb.ToString(), "quit", true) == 0);

                data = sb.ToString();

                sb.Length = 0; // Clear buffer

                Console.WriteLine("Text received from client:");
                Console.WriteLine(data);

                StringBuilder response = new StringBuilder();
                response.Append("Received at ");
                response.Append(DateTime.Now.ToString());
                response.Append("\r\n");
                response.Append(data);

                // Echo the data back to the client.
                byte[] sendBytes = Encoding.ASCII.GetBytes(response.ToString());
                networkStream.Write(sendBytes, 0, sendBytes.Length);

                // Client stop processing  
                if (bQuit)
                {
                    networkStream.Close();
                    ClientSocket.Close();
                    ContinueProcess = false;
                }
            }
        }

        public void Close()
        {
            networkStream.Close();
            ClientSocket.Close();
        }

        public bool Alive
        {
            get
            {
                return ContinueProcess;
            }
        }

    } // class ClientHandler 



     
}

Jochen Arndt

Тогда отправляйте данные не клиенту а, а клиенту В.

Но при этом б не будет клиентом. B должен слушать, а ваш сервер должен подключаться и отправлять. То есть:
Сервер выступает в качестве клиента и системы в качестве сервера.

F-ES Sitecore

Вам придется внести довольно существенные изменения. То, что делает ваш код, - это ожидание сообщения, и когда он получает сообщение, он запускает клиент, который просто читает сообщение, затем отправляет ответ отправителю, а затем отключается. Чтобы отправить сообщение кому-то, кроме отправителя, вам нужно будет знать, кто этот человек, и ваш существующий код не поддерживает список клиентов, он просто обрабатывает сообщения на специальной основе.

Вам нужно вести список подключенных клиентов и слушать их всех. Когда приходит сообщение от одного из них, вы просматриваете список подключенных клиентов и отправляете сообщение каждому по очереди.

0 Ответов