0

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

这是一些示例代码:

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

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

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

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

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

4

2 回答 2

1

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

对于许多应用程序而言,纯 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();
}

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

于 2012-09-27T23:14:23.057 回答
0

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

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

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

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

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

于 2012-09-27T17:56:38.557 回答