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

时间:2011-04-28 19:16:10

标签: c# .net sockets msdn

嘿大家,你们这里的人很棒,我得到了很多问题的回答,它帮助了很多。

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

我稍微对它进行了修改,它可以解决我需要做的事情。问题是目前的问题。这允许一次在一个客户端之间发送/接收。我需要能够确定连接到所述服务器的特定客户端,并向他们发送消息。

如何修改上述示例以包含每个连接的标识符,或至少包含一组标识符,以便我可以向我发送消息。

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

我是.net的新手,尤其是socket服务器编程。任何帮助都会很棒!

编辑:我一直在敲打砖墙,我听说在“州对象”中添加了需要的变量,问题是它会随着每个连接而更新。我需要知道谁是连接的,所以我可以向连接的客户端发送消息!

有什么想法吗?

1 个答案:

答案 0 :(得分:0)

我们创建的其中一个工具也有类似的情况(我没有直接使用它,但解决方案似乎工作正常)。每次我们收到一个客户端时,我们将相关信息存储在一个类中(类似于示例中的StateObject类),并将该类添加到ArrayList(工作正常)但我想更好的解决方案是将类存储在一个字典中:

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

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

// 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及其底层Stream存储在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
}

由您自己决定哪种方法最适合您的需求。希望这有帮助,并为您提供可行的解决方案。