C#中的TCP / IP多客户端连接

时间:2017-03-26 10:25:11

标签: c# tcp client-server

我编写了客户端和服务器应用程序,有以下代码:

客户端:

using System.Net.Sockets;
using System.Net;
using System.IO;
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;

namespace Client
{
    class Program
    {
        private static TcpClient    client = new TcpClient();
        private static StreamReader reader;
        private static StreamWriter writer;

        private static bool         refresh;
        private static List<string> messages = new List<string>();

        public static void Main()
        {
            Console.Title = "Client";

            do //try to connect
            {
                Console.WriteLine("Connecting to server...");

                try
                {
                    client.Connect(IPAddress.Parse("127.0.0.1"), 8080);
                }
                catch (SocketException) { }

                Thread.Sleep(10);
            } while (!client.Connected);

            // \/ CONNECTED \/

            Console.WriteLine("Connected.");

            reader = new StreamReader(client.GetStream());
            writer = new StreamWriter(client.GetStream());

            var sendTask       = Task.Run(() => SendMessage());          //task for sending messages
            var recieveTask    = Task.Run(() => RecieveMessage());       //task for recieving messages
            var updateConvTask = Task.Run(() => UpdateConversation());   //task for update console window

            Task.WaitAll(sendTask, recieveTask); //wait for end of all tasks
        }

        private static void SendMessage()
        {
            string msgToSend = string.Empty;
            do
            {
                Console.WriteLine("Enter a message to send to the server");
                msgToSend = Console.ReadLine();
                writer.WriteLine(msgToSend);
                writer.Flush();
            } while (!msgToSend.Equals("Exit"));
            EndConnection();
        }

        private static void RecieveMessage()
        {
            try
            {
                while (client.Connected)
                {
                    //Console.Clear();
                    string msg = reader.ReadLine();

                    if(msg != string.Empty)
                    {
                        if (msg == "%C") //special message from server, clear messages if recieve it
                        {
                            messages.Clear();
                        }
                        else
                        {
                            messages.Add(msg);
                            refresh = true; //refresh console window
                        }
                    }
                    //Console.Clear();
                    //Console.WriteLine(msgFromServer);
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
            }
        }

        private static void UpdateConversation()
        {
            //string conversationTmp = string.Empty;

            try
            {
                while (true)
                {
                    if (refresh) //only if refresh
                    {
                        refresh = false;
                        Console.Clear();
                        messages.ForEach(msg => Console.WriteLine(msg)); //write all messages
                        Console.WriteLine();
                    }
                }
            }
            catch (Exception) { }
        }

        private static void EndConnection()
        {
            reader.Close();
            writer.Close();
            client.Close();
        }

    }
}

服务器:

using System;
using System.Net;
using System.Net.Sockets;
using System.IO;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace Server
{
    class Program
    {
        private static List<Client> clients = new List<Client>();
        private static TcpListener  listener = null;
        private static StreamReader reader = null;
        private static StreamWriter writer = null;
        private static List<Task>   clientTasks = new List<Task>();
        private static List<string> messages = new List<string>();

        public static void Main()
        {
            Console.Title = "Server";
            try
            {
                listener = new TcpListener(IPAddress.Parse("127.0.0.1"), 8080);
                listener.Start();
                Console.WriteLine("Server started...");

                var connectTask = Task.Run(() => ConnectClients());
                //var listenTask = Task.Run(() => ListenClients());

                Task.WaitAll(connectTask);
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
            }
            finally
            {
                if (listener != null)
                {
                    listener.Stop();
                }
            }
        }

        private static void ConnectClients()
        {
            Console.WriteLine("Waiting for incoming client connections...");
            while (true)
            {
                if (listener.Pending()) //if someone want to connect
                {
                    clients.Add(new Client(listener.AcceptTcpClient(), "Client: " + (clients.Count + 1)));
                    Console.WriteLine(clients[clients.Count - 1].clientName + " connected to server.");
                    clientTasks.Add(Task.Run(() => HandleClient(clients[clients.Count - 1]))); //start new task for new client
                }
            }
        }

        private static void HandleClient(Client TCPClient)
        {
            string s = string.Empty;
            writer = new StreamWriter(TCPClient.client.GetStream());
            reader = new StreamReader(TCPClient.client.GetStream());

            try
            {
                while (!(s = reader.ReadLine()).Equals("Exit") || (s == null))
                {
                    if(!TCPClient.client.Connected)
                    {
                        Console.WriteLine("Client disconnected.");
                        clients.Remove(TCPClient);
                    }

                    Console.WriteLine("From client: " + TCPClient.clientName  + " -> " + s);
                    messages.Add(TCPClient.clientName + ": " + s); //save new message
                    //Console.WriteLine(s);

                    foreach (Client c in clients) //refresh all connected clients
                    {
                        c.writer.WriteLine("%C"); //clear client
                        foreach (string msg in messages)
                        {
                            c.writer.WriteLine(msg);
                            c.writer.Flush();
                        }
                    }
                }
                CloseServer();
            }
            catch (Exception e) { Console.WriteLine(e); }
        }

        private static void CloseServer()
        {
            reader.Close();
            writer.Close();
            clients.ForEach(tcpClient => tcpClient.client.Close());
        }
    }
}

客户端类代码:

class Client
{
    public TcpClient client;
    public StreamWriter writer; //write to client
    public string clientName;

    public Client(TcpClient client, string clientName)
    {
        this.client = client;
        reader = new StreamReader(client.GetStream());
        writer = new StreamWriter(client.GetStream());
        this.clientName = clientName;
    }
}

客户端将消息发送到存储所有客户端的服务器,然后将整个会话发送回所有客户端。

客户端类包含有关已连接客户端的信息,服务器有一个客户端实例列表。

对于一个客户端它运行良好,但是当我有两个客户端时,在开始时它也可以工作,但是在一些消息之后,一个客户端向它们发送消息两个,而另一个客户端无法发送消息。

请帮忙,我是TCP通讯的新手。

1 个答案:

答案 0 :(得分:0)