【问题标题】:Storing connected clients?存储连接的客户端?
【发布时间】:2012-09-19 14:05:15
【问题描述】:

我目前正在学习和使用客户端/服务器,但我在如何存储连接方面遇到了一些困难。

这里是一些示例代码:

while (_isRunning)
{
    if (!tcpListener.Pending())
    {
        Thread.Sleep(200);
        continue;
    }

    TcpClient client = tcpListener.AcceptTcpClient();
    // TODO: handle connection
}

我知道我将有一个处理程序来接收/发送数据到给定的客户端,但是,只有处理程序不允许我做一些事情,比如知道有多少客户端连接,发送广播消息或关闭消息到全部。

将客户存储在列表中会很好还是应该存储其他任何东西?

在这种情况下存储连接的客户端的正确方法是什么?

【问题讨论】:

  • DictionaryList 可能在这里有用。 List<TcpClient> 应该足够了。
  • @Matthew 是的,但我的意思是,一个列表就足够了吗?除了 TcpClient 之外,我是否应该保留任何其他信息以使我的连接客户端列表?我只是在寻找一些关于如何做到这一点的有用方法的参考
  • 这取决于您感兴趣的信息。如果您只关心连接数和能够广播消息,那么简单的 TcpClient 列表就足够了。

标签: c# winforms .net-4.0 tcpclient tcplistener


【解决方案1】:

对于服务器,您通常不会对套接字感兴趣,而是对套接字的用途感兴趣。我将采取的方法是有一个类来管理客户端和服务器之间对话的服务器端。这个类将基于一个线程,因此其想法是每次接受连接时,您都会分离一个线程来处理对话,并且在该线程中是连接服务器端的套接字。

此时您将管理各种线程而不是单个套接字。这是更高层次的抽象,更有用。

您如何管理线程取决于您想要做什么。可能你真的不想担心它。由于每个线程都在做自己的事情,当它完成时,它只是关闭它的 TCP 连接并退出。

但是,在它退出之前,线程类会处理对话的服务器端。

我建议你检查这个 stackoverflow,Best way to accept multiple tcp clients

【讨论】:

    【解决方案2】:

    对于最常见的使用模式,保持连接客户端的List 就足够了。主要兴趣点将是决定:what 的列表?

    对于许多应用程序来说,纯 TCP 功能使用起来并不方便,因此您需要在其上添加一层,将流转换为更像消息队列的东西,可以从中提取整个独立的“消息”;这些消息的格式取决于您的应用程序。

    我挖掘了我的一个旧项目,它是一个客户端-服务器配置,其中多个客户端连接到服务器并提供远程控制功能。在该项目中,服务器保留List<ConnectedClient>,其中:

    // This is the whole actual class
    private class ConnectedClient
    {
        public TcpMessageConnection Connection { get; private set; }
    
        public bool ConnectedEventRaised { get; set; }
    
        public ConnectedClient(TcpMessageConnection connection)
        {
            this.Connection = connection;
        }
    }
    

    TcpMessageConnection 看起来像:

    // Only class outline shown
    public class TcpMessageConnection
    {
        private readonly MessageStream messageStream; // another custom class
    
        private readonly TcpClient tcpClient;
    
        public EndPoint RemoteEndPoint { get; private set; } // who connected here?
    
        public MessageReader MessageReader { get; } // messageStream.Reader
    
        public MessageWriter MessageWriter { get; } // messageStream.Writer
    
        public bool IsCurrentlyDisconnecting { get; private set; }
    
        public void Close();
    }
    

    MessageReaderMessageWriter 一起(完成真正的繁重工作),这足以实现基于异步的服务器,该服务器在单个线程上为多个客户端提供服务。

    【讨论】:

    • 这很有趣,那个项目是开源的吗?我很想检查更多。我喜欢它如何捆绑连接的用户,很容易检索一些有用的数据,如 IP,我假设你的关闭是发送关闭或关闭该客户端?
    • @Guapo:不是开源的,抱歉。 Close 简单地关闭MessageStream(这反过来又关闭了TcpClientStream)和TcpClient 本身。 IsCurrentlyDisconnecting 在此之前设置为 true 并用作保护,因此应用程序的其余部分不必担心垃圾邮件关闭并导致某种错误。
    猜你喜欢
    • 1970-01-01
    • 2023-04-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-13
    • 1970-01-01
    • 2017-03-21
    • 2010-11-18
    相关资源
    最近更新 更多