c#异步套接字服务器示例-如何向所有客户端发送消息

本文关键字:客户端 消息 套接字 异步 服务器 | 更新日期: 2023-09-27 17:54:10

大家好,你们真是太棒了,我得到了很多问题的答案,这对我帮助很大。

我已经从MSDN修改了这个示例服务器异步套接字服务器:http://msdn.microsoft.com/en-us/library/fx6588te.aspx

我已经稍微修改了它,它的工作与我需要做的治疗。问题是在当下。这允许一次在一个客户端之间发送/接收。我需要能够精确定位连接到所述服务器的特定客户端,并向它们发送消息。

我如何修改上面的例子,为每个连接包含一个标识符,或者至少包含一组标识符,以便我可以向我需要的人发送消息。

客户端可能有大约6-10个独立变量,每个都需要根据需要进行过滤(例如,将数据发送到组中的一组客户端)。我有一个旧的阻塞服务器,它不够高效,我只是有一个二维数组,它完美地完成了这项工作。在所有筛选数组的客户端周围循环就可以了。但是在上面的例子中,连接似乎没有被识别或存储,你会推荐什么,哪里最容易存储它?

我是一个相当新的。net,特别是套接字服务器编程。任何帮助都太好了!

edit:我一直在碰壁,我听说虽然在"状态对象"中添加了需要的变量,但问题是它与每个连接都更新。我需要知道谁是连接的,所以我可以发送消息到连接的客户端!

任何想法?

c#异步套接字服务器示例-如何向所有客户端发送消息

我们创建的一个工具也有类似的情况(我没有直接处理它,但解决方案似乎工作得很好)。每次我们接收到客户端,我们将相关信息存储在一个类中(类似于示例中的StateObject类),并将该类添加到ArrayList中(这很好),但我认为更好的解决方案是将类存储在Dictionary中:

http://msdn.microsoft.com/en-us/library/xfhwa508.aspx

Dictionary类允许您将Key映射到对象。这允许您使用唯一键轻松访问对象。因此,在接收新客户端时,您可以为该客户端创建一个您希望的任何方式的ID(这可能只是一个整数,每次客户端连接时都会增加),创建一个状态对象类并在该类中存储所需的相关信息,然后将密钥类对添加到字典中,因此类似于:

// Global definition of Client dictionary
// The first argument within <> is the key type, the second argument
// is the type of object that key will map to
Dictionary<int, StateObject> Clients = new Dictionary<int, StateObject>();
// Accept client callback
public static void AcceptCallback(IAsyncResult ar)
{
    // Get the socket that handles the client request.
    Socket listener = (Socket) ar.AsyncState;
    Socket handler = listener.EndAccept(ar);
    StateObject client = new StateObject();
    // Then set all the variables of client here
    Clients.Add(ID, client);
}

注意:无论您如何创建您的id,它们必须是字典中每个条目的唯一。

我的建议是将每个接受的套接字客户端的处理程序存储在StateObject中。通过这种方式,您始终可以访问可以向每个连接的客户端发送信息的句柄(这就是我们使用Tcp连接的方式),我们将TcpClient及其底层流存储在我们的StateObject类中,然后通过这些变量与每个客户端通信。我假设这也是可能的套接字吗?)

现在有了存储的所有信息,您可以使用字典中的ID键来确定要与哪些客户端通信。使用LINQ可以得到一个很好的一行选择命令:

// Selects state objects from Clients dictionary where ID has a value greater than 5
IEnumerable<StateObject> Clients.Where(c => c.Key > 5).Select(c => c.Value);

(我认为这是有效的LINQ查询,但它需要检查,它本质上是说从客户端列表中选择每个StateObject,其中ID大于5)

如果你不想让id以这种方式标识客户端,你可以循环遍历字典中的每个StateObject,并检查内部变量,看看你是否向客户端发送消息。比如:

foreach (StateObject client in Clients.Values)
{
    if (client.ImportantVariable == true)
        // Send client information via socket here
}
哪一种方法最适合你的需要完全由你来决定。