【问题标题】:How to handle multiple active connections in a TCP C# socket server?如何处理 TCP C# 套接字服务器中的多个活动连接?
【发布时间】:2016-09-22 16:33:28
【问题描述】:

到目前为止,我的套接字服务器非常简单:

        public static void listen()
    {
        TcpListener server = null;
        IPAddress address = IPAddress.Parse("127.0.0.1");
        try
        {
            server = TcpListener.Create(5683);
            server.Start();

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


        while (true)
        {
            Thread.Sleep(10);
            TcpClient client = server.AcceptTcpClient();
            Console.WriteLine("Accepted Client");

            Thread thread = new Thread (new ParameterizedThreadStart(SwordsServer.ClientHandler));
            thread.IsBackground = true;
            thread.Start(client);
        }
    }

    public static void ClientHandler(object c)
    {
        TcpClient client = (TcpClient)c;
        NetworkStream netstream = client.GetStream();
        bool connected = true;
        while (connected)
        {
            Thread.Sleep(10);
            try
            {
                byte[] bytes = new byte[client.ReceiveBufferSize];                   
                netstream.Read(bytes, 0, bytes.Length);
                Console.WriteLine("got data");
                netstream.Write(bytes, 0, bytes.Length);

            }
            catch (Exception e)
            {
                connected = false;
                Console.WriteLine(e);
                Console.WriteLine(e.StackTrace);
            }
        }
    }

我的问题是,在概念层面上,您将如何关注每个唯一的 client 并将来自其他线程的更新发送到特定客户端?

例如,如果我有特定客户的数据,我如何联系该客户而不是广播它?或者,如果客户端不再连接,我怎么知道?

提前感谢您的帮助!

【问题讨论】:

  • 添加列表对象 List clients.
  • 但是我如何引用该列表中的特定 TCPClient 呢?我如何区分它们?
  • 一种方法是使用客户端的IP地址。或者给每个客户一个 ID。

标签: c# sockets tcp


【解决方案1】:

您接受多个连接的实现会创建匿名客户端,这意味着在超过 1 个连接之后您将无法识别正确的客户端。如果识别是问题,那么您可以做一件事,让客户端向服务器发送一个标识符,如“Client1”。创建一个 Dictionary 并在您的方法 ClientHandler() 中,从客户端读取标识符并将 TCPClient 的对象添加到字典中。

所以修改后的代码是这样的:

 Dictionary<string, TCPClient> dictionary = new Dictionary<string, TCPClient>();


 public static void ClientHandler(object c)
    {
        TcpClient client = (TcpClient)c;
        NetworkStream netstream = client.GetStream();
        bool connected = true;
        while (connected)
        {
            Thread.Sleep(10);
            try
            {
                byte[] bytes = new byte[client.ReceiveBufferSize];

                //read the identifier from client
                netstream.Read(bytes, 0, bytes.Length);

                String id = System.Text.Encoding.UTF8.GetString(bytes);

                //add the entry in the dictionary
                dictionary.Add(id, client);
                Console.WriteLine("got data");
                netstream.Write(bytes, 0, bytes.Length);

            }
            catch (Exception e)
            {
                connected = false;
                Console.WriteLine(e);
                Console.WriteLine(e.StackTrace);
            }
        }
    }

请注意:您的应用程序应该足够智能,可以动态决定更新应该发送到哪个客户端。

【讨论】:

  • 是的,这就是我在 UDP 程序中所做的,我只是使用它们的 IP/Socket 元组作为其客户端对象值的键。谢谢!
  • 嗨,Rishabh Kumar!最近我遇到了类似的问题。我想在像您这样的解决方案中,但是当服务器运行很长时间并且有很多客户端时,我的问题就会出现。事情是应用程序开始创建很多线程,并且在我再次重新启动它之前一段时间不接受更多连接。那么,你能帮忙吗?谢谢!
  • @RishabhKumar 好吧,这是我的代码,正如我告诉你的那样,一段时间后我的内存出现了一些问题。谢谢你帮助我! pastebin.com/sx6iVnZD
猜你喜欢
  • 2014-01-06
  • 1970-01-01
  • 2015-05-15
  • 1970-01-01
  • 1970-01-01
  • 2010-12-07
  • 1970-01-01
  • 2013-03-19
  • 1970-01-01
相关资源
最近更新 更多