Как обрабатывать несколько клиентов TCP для связи - PullRequest
1 голос
/ 05 июня 2011

Я разрабатываю многопользовательское TCP/IP серверное приложение, которое может принимать некоторые команды от разных клиентов, и на основе этих команд сервер будет выполнять некоторые действия и соответственно отправлять ответ клиенту.

Мой вопрос заключается в том, как обработать несколько клиентов, чтобы отправить соответствующие данные обратно этому конкретному клиенту после обработки. Как передать ссылку TCP client при отправке данных на сервер и как сохранить ее, чтобы ответ можно было отправить обратно на соответствующий TCPClient.

Я использую TCPlistner для создания TCPClient объекта. Это oTCPClient = oTCPListener.AcceptTcpClient();. Итак, как создать соответствующие NetworkStream для каждого TCPClient для связи.

Ответы [ 2 ]

0 голосов
/ 13 апреля 2016

Вот пример сервера, который может обрабатывать несколько клиентов и отвечать на несколько клиентов

class MultyClientServer
{
    private static int bufferSize = 2048;
    private static byte[] buffer = new byte[bufferSize];
    private static List<Socket> clientSockets = new List<Socket>();
    private static Socket serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);


    static void Main(string[] args)
    {
        Console.Title = "Server";
        SetupServer();
        Console.ReadKey();
        CloseAllSockets();
    }

    private static void SetupServer()
    {
        Console.WriteLine("Settings Up Server Plz Wait");
        serverSocket.Bind(new IPEndPoint(IPAddress.Any, YOUR PORT HERE));
        serverSocket.Listen(10);
        serverSocket.BeginAccept(new AsyncCallback(CallBack), null);
        Console.WriteLine("Server Made");
    }

    private static void CallBack(IAsyncResult e)
    {
        try
        {
            Socket socket = serverSocket.EndAccept(e);
            clientSockets.Add(socket);
            Console.WriteLine("Client Connected");
            socket.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallBack), socket);
            serverSocket.BeginAccept(new AsyncCallback(CallBack), null);
        }
        catch (Exception ex) { Console.WriteLine(ex.Message); }
    }

    private static void ReceiveCallBack(IAsyncResult e)
    {
        try
        {
            Socket socket = (Socket)e.AsyncState;
            int received;
            try
            {
                received = socket.EndReceive(e);
            }
            catch (SocketException)
            {
                Console.WriteLine("Client forcefully disconnected");
                socket.Close();
                clientSockets.Remove(socket);
                return;
            }
            byte[] dataBuf = new byte[received];
            Array.Copy(buffer, dataBuf, received);

            string text = Encoding.ASCII.GetString(dataBuf);
            Console.WriteLine("Client request: " + text);

            string response = string.Empty;


            try
            {
                if (command.ToLower() == "What Time is it")
                {
                    response = DateTime.Now.ToString();
                }
                else if (command.ToLower() == "Whats your name")
                {
                    response = "Tyler Gregorcyk";
                }
                else
                {
                    response = "Invaled";
                }
            }
            catch (Exception et) { Console.WriteLine(et.Message); socket.Close(); clientSockets.Remove(socket); }


            if(response == string.Empty)
            {
                response = "Invaled";
            }

            if (response != string.Empty)
            {
                Console.WriteLine("Sent To Client: " + response);
                byte[] data = Encoding.ASCII.GetBytes(response);
                socket.Send(data);
                serverSocket.BeginAccept(new AsyncCallback(CallBack), null);
            }

            conn.Close();
            socket.BeginReceive(buffer, 0, bufferSize, SocketFlags.None, ReceiveCallBack, socket);
        }
        catch (Exception) { }
    }

    private static void CloseAllSockets()
    {
        foreach (Socket socket in clientSockets)
        {
            socket.Shutdown(SocketShutdown.Both);
            socket.Close();
        }

        serverSocket.Close();
    }
}

Кстати, это отредактированная версия учебника на YouTube: https://www.youtube.com/watch?v=xgLRe7QV6QI

0 голосов
/ 05 июня 2011

Я бы создал ConnectedClient класс, который принимает TCPClient в конструкторе, а затем запустил поток в этом объекте, который читает NetworkStream из TCPClient для входящих данных.У вас также может быть метод в ConnectedClient для отправки данных.Всякий раз, когда вы получаете данные и хотите ответить или переслать сообщение, вы можете вызвать SendData для одного или нескольких из сохраненных ConnectedClient объектов.

...