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

发布于 2024-11-03 22:34:00 字数 676 浏览 2 评论 0原文

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

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

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

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

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

我对 .net 尤其是套接字服务器编程相当陌生。任何帮助都会很棒!

编辑:我一直在为此而苦苦挣扎,我听说虽然在“状态对象”中添加所需的变量,但问题是它会随着每次连接而更新。我需要知道谁已连接,以便我可以向连接的客户端发送消息!

有什么想法吗?

Hey everyone, You guys here are awesome, I'm getting so many questions answered, its helping so much.

I have modified this example server Asynchronous Socket Server from MSDN:
http://msdn.microsoft.com/en-us/library/fx6588te.aspx

I have modified it slightly and it works a treat with what I am needing to do. the issue is at the moment. That is allows the send/receive between one client at a time. I need to be able to pinpoint specific clients that are connected to said server, and send a message to them.

How can I modify the above example to include an identifier for each connection, or at least a set of identifiers so that I can send messages to whom I need to.

The clients may have around 6-10 independent variables, each need to be filtered as needed (for example, sending data to a set of clients in a group). I had an old blocking server that wasn't efficient enough, I simply had a 2 dimension array which did the job perfectly. A loop around all clients filtering the array was fine. But in the above example, the connections dont seem to be identified or stored, what would you recommend and where would it be easiest to store it?

I'm fairly new to .net and especially socket server programming. Any help would be great!

edit: I have been banging my head against a brick wall about this, I heard though of adding the variables in need within the 'state object' the issue is that it renews with each connection. I need to know who is connected so I can send messages to the connected clients!

Any idea?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

遇到 2024-11-10 22:34:00

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

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 及其底层 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
}

这实际上取决于您来决定哪种方法最适合您的需求。希望这对您有所帮助并且是一个可行的解决方案。

We had a similar situation for one of the tools we created (I didn't work directly on it but the solution seems to work fine). Every time we received a client we stored the relevant information in a class (similar to the StateObject class in the example) and added that class to an ArrayList (which works fine) but I suppose a nicer solution would be store the classes in a Dictionary:

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

The Dictionary class allows you to map a Key to an object. This allows you to easily access objects using a unique key. So on receiving a new client you could create an ID for that client which ever way you wish (this might just be an integer which increments every time a client connects), create a state object class and store the relevant information you need within that class, then add the Key Class pair to the dictionary, so something similar to:

// 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);
}

Note: However you want to create your IDs they must be unique for each entry within the Dictionary.

My advice would be to store the handler for each accepted socket client within the StateObject. This way you always have access to a handle which can send information to each individual connected client (this is how we did it with our Tcp connection, we stored the TcpClient and its underlaying Stream in our StateObject class and then communicated with each client through these variables. I'm assuming this is possible with Sockets too?)

Now with all the information stored you could either use the ID keys within the dictionary to identify which clients to communicate with. Using LINQ gives you a nice one line select command:

// 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);

(I think this is the valid LINQ query but it will need checking, its essentially saying select each StateObject from the client list, where the ID is greater than 5)

If you don't want the IDs to identify clients in this way you could loop through every StateObject within the dictionary and check internal variables to see whether you send the client a message or not. Something like:

foreach (StateObject client in Clients.Values)
{
    if (client.ImportantVariable == true)
        // Send client information via socket here
}

Its really up to you to decide which method would best suit your needs. Hope this helps and is a viable solution for you.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文