【问题标题】:what is benefit from socket reuse in C#C# 中的套接字重用有什么好处
【发布时间】:2010-11-09 11:29:45
【问题描述】:

我正在开发开源套接字服务器库:https://sourceforge.net/projects/socketservers/

我想在这个库中添加套接字重用功能。我已经实现了这个功能的草案,但我在测试中看不到任何好处。客户端通过8个项目对服务器进行32K连接-断开并测量时间。但是,重用套接字和不重用套接字之间没有区别 - 此测试经过了相同的时间。

我在测试中做错了什么?

重用套接字时服务器应该获得什么好处,以及如何衡量这种好处?

【问题讨论】:

    标签: c# sockets reusability


    【解决方案1】:

    我可以从非托管的角度解释发生了什么以及如何使用DisconnectEx(),也许有人可以将其映射到托管场景。

    在非托管代码中,您将使用DisconnectEx() 将套接字重用于后续的AcceptEx()ConnectEx() 调用,更可能是前者。因此,您最初会创建 x 个套接字并使用 AcceptEx() 发布重叠的异步接受操作。当客户端连接到这些挂起的连接时,您将执行服务器操作,然后在最后调用套接字上的 DisconnectEx() 并使用该套接字发布一个新的 AcceptEx()。这避免了此时创建新套接字的需要,因此对服务器来说更有效。性能差异可能很小,但值得在接受大量短期连接的重负载服务器上使用。

    所以我建议你发布一些代码来展示你在调用Disconnect(true)之后如何重用你的套接字......

    【讨论】:

    • 谢谢。我可以将开发版本上传到 sourceforge 的 SVN,但是我使用了几个类来重用套接字,它需要一些时间来理解逻辑。
    • 我同意你的理论。我已经以这种方式实现了它(除了我之前没有创建套接字,而是通过 Accept 创建重用)。但我在我的测试中没有任何性能差异。测试客户端创建 4096 次 8 次短期连接 - 没有区别。
    • 确定套接字重用在实际应用中有任何性能优势吗?
    • 如何复用accept创建的socket?有多少并发连接,连接发生的速度有多快? CPU负载多少?等等。正如我所说,性能提升可能非常小。在非托管代码中,您通过重用套接字来避免一些工作,因此您应该完成更多其他工作。
    • 是的,我知道这取决于很多因素。有没有简单的测试?我在 .net 应用程序中测量(新的 Socket() 和绑定)操作和断开连接(重用) - 几乎没有区别(~5%)。
    【解决方案2】:

    问题是操作系统或运行时是否在调用新套接字时不自动执行重用。
    Socket.Disconnect 方法文档指向这个方向:

    关闭套接字连接并允许重新使用套接字。
    所以这似乎是一个过度优化。

    【讨论】:

    • msdn 没有关于在 winapi 和 .net Socket 类中自动重用套接字的任何意义。
    • 谢谢回复,我不明白Socket.Disconnect的点在哪里?我使用 Socket.Disconnect(true) 进行套接字重用和 Socket.Close 不重用套接字。
    • 为每个连接维护一个 TCP 控制块(TCB – 使用 0.5 KB 页面池和 0.5 KB 非页面池的数据结构)。 TCB 被预先分配并存储在一个表中,以避免每次创建/关闭连接时都花时间分配/解除分配 TCB。 TCB 表支持 TCB 的重用/缓存并改进内存管理,但静态大小限制了 TCP 可以同时支持的连接数(Active + TIME_WAIT)。
    • 我找不到所有TCB都用完时winsock在做什么,但是winsock重用socket之前的样子。
    【解决方案3】:

    如果您的意思是 SO_REUSEADDR 或 SO_REUSEPORT:

    套接字重用非常重要,例如您的服务器崩溃了,但仍然存在连接。

    如果重新启动服务器,通常必须等到操作系统正常关闭这些连接,然后才能将套接字重新绑定到该端口。

    这可能意味着,一些严重依赖您的服务器的进程在重新启动之前会停止。

    由于套接字重用功能,您可以规避这个问题。

    这可能还有其他用途,但我现在只能想到这个。 希望对您有所帮助。

    【讨论】:

    • 谢谢。不,我的意思是 DisconnectEx 带有 TF_REUSE_SOCKET 标志,而不是 win api 中的 closesocket 函数,然后再次使用断开连接的套接字。或者我在 .net 中使用 Socket.Disconnect(true)
    猜你喜欢
    • 2018-02-14
    • 2011-05-16
    • 2011-08-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多