gpt4 book ai didi

sockets - .Net 4.5 TCP Server可扩展到数千个连接的客户端

转载 作者:行者123 更新时间:2023-12-03 11:50:33 27 4
gpt4 key购买 nike

我需要使用C#.NET 4.5+构建TCP服务器,它必须能够舒适地处理至少3,000个连接的客户端,这些客户端每10秒发送一次消息,消息大小从250到500字节。

数据将被分流到另一个进程或队列中,以进行批处理和记录。

我还需要能够选择一个现有客户端,以便在Windows窗体应用程序中发送和接收消息(大于500字节)。

我之前没有构建过这样的应用程序,因此我的知识是基于我在网上找到的各种问题,示例和文档。

我的结论是:

  • 非阻塞异步是一种解决方法。避免创建多个线程和阻塞IO。
  • SocketAsyncEventArgs-是复杂的,实际上仅对于非常大的系统才需要,顺便说一句,什么构成了非常大的系统? :-)
  • BeginXXX方法就足够了(EAP)。
  • 使用TAP我可以通过使用Task.Factory.FromAsync来简化3.,但它只会产生相同的结果。
  • 使用全局集合来跟踪连接的tcp客户端

  • 我不确定的是:
  • 与TCP Client集合进行交互时,我应该使用ManualResetEvent吗?我认为asyc事件将需要锁定对此集合的访问。
  • 在之后,我检测到断开连接的客户端的最佳方法是我调用了BeginReceive。我发现调用被卡在等待响应,因此需要清理。
  • 将消息发送到特定的TCP客户端。我在考虑自定义TCP session 类中的功能以发送消息。同样,在异步模型中,我是否需要创建一个基于计时器的进程来检查消息队列,还是在可以访问TcpClient和关联流的TCP Session类上创建事件?真的对这里的意见感兴趣。
  • 我想在整个服务中使用一个线程,并在其中使用非阻塞的主体,尤其是在1. ManualResetEvent等的上下文中,我应该特别注意些什么。

  • 感谢您的阅读。我渴望听到 build 性的想法或与最佳做法/示例的链接。自从我用C#编码以来已经有一段时间了,如果我的某些问题很明显,我深表歉意。任务,异步/等待对我来说是新的! :-)

    最佳答案

    I need to build a TCP server using C# .NET 4.5+



    好吧,首先要确定的是它是否必须是基本的TCP/IP。 如果可以使用,请编写使用更高级别抽象的信号,例如SignalR或WebAPI。如果您可以使用WebSockets(SignalR)编写代码,那么请执行此操作,永远不要回头。

    您的结论听起来不错。只是一些注意事项:

    SocketAsyncEventArgs - Is complex and really only needed for very large systems, BTW what constitutes a very large system? :-)



    就连接数量而言,它并不是一个“大型”系统。更多的是系统中的流量-每秒读/写数的问题。
    SocketAsyncEventArgs唯一要做的就是使您的I/O结构可重用。 Begin*/ End*( APM)API将为每个I/O操作创建一个新的 IAsyncResult,这会给垃圾收集器造成压力。 SocketAsyncEventArgs本质上与 IAsyncResult相同,只是可重用。请注意,网上有一些使用 SocketAsyncEventArgs API而不重用 SocketAsyncEventArgs结构的示例,这是完全荒谬的。

    而且这里没有准则:较重的硬件将能够使用APM API来获得更多流量。通常,您应该构建准系统APM服务器并首先对其进行负载测试,并且如果它不能在目标服务器的硬件上运行,则仅移至SAEA。

    接下来的问题:

    Should I use a ManualResetEvent when interacting with the TCP Client collection? I presume the asyc events will need to lock access to this collection.



    如果您使用的是基于 TAP的包装器,则默认情况下 await将在捕获的上下文中恢复。我在 my blog post on async / await 中对此进行了解释。

    您可以在此处采取两种方法。我已经成功地编写了可靠的高性能单线程TCP/IP服务器;现代代码的等效方法是使用 my AsyncContextThread class之类的东西。它提供了一个上下文,默认情况下将导致 await在同一线程上恢复。

    单线程服务器的好处是只有一个线程,因此不需要同步或协调。但是,我不确定单线程服务器的扩展能力。您可能需要尝试一下,看看它可以承受多少负载。

    如果确实需要多个线程,则可以仅在线程池上使用 async方法。 await将没有捕获的上下文,因此将在线程池线程上继续。在这种情况下,是的,您需要协调对任何共享数据结构(包括TCP客户端集合)的访问。

    请注意,SignalR将为您处理所有这一切。 :)

    Best way to detect a disconnected client after I have called BeginReceive. I've found the call is stuck waiting for a response so this needs to be cleaned up.



    这是 half-open problem,我将在我的博客中进行详细讨论。解决此问题的最佳方法(IMO)是定期向每个客户端发送“空转” keepalive消息。

    如果无法修改协议(protocol),那么下一个最佳解决方案是在无通信超时后立即关闭连接。这就是HTTP“持久”/“保持 Activity ”连接决定关闭的方式。还有另一种可能的解决方案(更改套接字上的keepalive数据包设置),但是它不那么容易(需要p/Invoke)并且存在其他问题(路由器并不总是尊重,也不是所有OS TCP/IP堆栈都支持等)。

    哦,SignalR会为您处理。 :)

    Sending messages to a specific TCP Client. I'm thinking function in custom TCP session class to send a message. Again in an async model, would I need to create a timer based process that inspects a message queue or would I create an event on a TCP Session class that has access to the TcpClient and associated stream? Really interested in opinions here.



    如果您的服务器可以将消息发送到任何客户端(即,不仅是请求/响应协议(protocol);服务器的任何部分都可以将消息发送到任何客户端而无需客户端请求更新),那么是的,您需要一个适当的队列发送请求的数量,因为您不能(可靠地)在套接字上发出多个并发写操作。但是,我不会让使用者基于计时器。有异步兼容的生产者/消费者队列(例如 BufferBlock<T> from TPL Dataflowit's not that hard to write one(如果您有 async-compatible locks and condition variables))。

    哦,SignalR会为您处理。 :)

    I'd like to use a thread for the entire service and use non-blocking principals within, are there anythings I should be mindful of espcially in context of 1. ManualResetEvent etc..



    如果您的整个服务都是单线程的,那么您根本不需要任何协调原语。但是,如果确实使用线程池而不是同步回主线程(出于可伸缩性原因),则需要进行协调。我有一个 coordination primitives library,您可能会发现它很有用,因为它的类型同时具有同步和异步API。例如,这允许一种方法在锁上阻塞,而另一种方法想要在锁上异步阻塞。

    您可能已经注意到围绕SignalR的主题重复出现。如果可能,请使用它!如果 必须编写一个简单的TCP/IP服务器,而 无法使用SignalR,则将您的初始时间估算值增加三倍。严重地。然后,您可以使用 TCP/IP FAQ blog series开始痛苦的TCP路径。

    关于sockets - .Net 4.5 TCP Server可扩展到数千个连接的客户端,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36617703/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com