我正在寻找人们在实现为客户端 TCP(或 UDP)请求提供服务的服务器应用程序时使用的任何策略:设计模式、实现技术、最佳实践等。

出于此问题的目的,我们假设请求的生命周期相对较长(几分钟),并且流量对时间敏感,因此响应消息时不可接受任何延迟。此外,我们既服务来自客户端的请求,又建立与其他服务器的连接。

我的平台是 .NET,但由于无论平台如何,底层技术都是相同的,因此我有兴趣查看任何语言的答案。

有帮助吗?

解决方案

现代方法是利用操作系统为您复用许多网络套接字,从而使您的应用程序只处理活动的流量连接。

每当您打开一个套接字时,它就会与一个选择器相关联。您使用单个线程来轮询该选择器。每当数据到达时,选择器都会指示套接字处于活动状态,您将该操作移交给子线程并继续轮询。

这样,每个并发操作只需要一个线程。打开但空闲的套接字不会占用线程。

其他提示

更复杂的方法是使用 IO 完成端口。(视窗) 使用 IO 完成端口,您可以留给操作系统来管理轮询,这使它可以在 NIC 驱动程序支持下使用非常高的优化级别。基本上,您有一个由操作系统管理的网络操作队列,并提供一个在操作完成时调用的回调函数。有点像(硬盘)DMA,但用于网络。

Len Holgate 几年前在 Codeproject 上写了一篇关于 IO 完成端口的精彩系列文章:http://www.codeproject.com/KB/IP/jbsocketserver2.aspx

和 我找到了一篇关于 .net 的 IO 完成端口的文章(虽然没有读过) http://www.codeproject.com/KB/cs/managementiocp.aspx

我还想说,与尝试编写可扩展的替代方案相比,使用完成端口很容易。问题是它们仅适用于 NT(2000、XP、Vista)

如果您直接使用 C++ 和 Win32,那么我建议您阅读有关重叠 I/O 和 I/O 完成端口的信息。我有一个免费的 C++、IOCP、客户端/服务器框架,具有完整的源代码,请参阅 这里 更多细节。

由于您使用的是 .Net,因此您应该考虑使用异步套接字方法,这样您就不需要为每个连接都有一个线程;我的这篇博客文章中有几个链接可能是有用的起点: http://www.lenholgate.com/blog/2005/07/disappointing-net-sockets-article-in-msdn-magazine-this-month.html (一些最好的链接位于原始帖子的评论中!)

你好,

我首先看一下您想要用于线程框架的隐喻。

也许是“领导跟随者”,其中线程正在侦听传入请求,当新请求进入时,它会执行工作,并且池中的下一个线程开始侦听传入请求。

或者线程池,其中同一线程始终侦听传入请求,然后将请求传递给线程池中的下一个可用线程。

您可能想参观 反应堆 Ace 组件部分以获得一些想法。

HTH。

干杯 抢

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top