【问题标题】:Does the creation of TcpClient have much overhead?TcpClient 的创建开销大吗?
【发布时间】:2023-03-21 16:45:01
【问题描述】:

我尝试使用 TcpClient 发送/接收数据。我做了两个实验,发现了一些有趣的东西。

我在日本的服务器和英国的服务器中设置了 TcpListener。我一直向 TcpListener 发送 500 个字节,当 TcpListener 将 10KB 发送回 TcpClient 时。在每个实验中,我保持这个发送/接收循环 500 次。

实验一:

在每个发送/接收循环中,我创建一个全新的 TcpClient(从创建之前开始计时)并发送/接收

实验 2:

对于所有循环,我只有一个 TcpClient,它与 TcpListener 保持连接并进行 500 次发送/接收。

结果:

一个循环的时间成本的平均值:

E1:1.8 秒,E2:0.49 秒。

我对这个结果感到非常惊讶。所以保持连接以持续发送/接收可以节省很多时间???将近 2/3 的时间。

这是真的吗???

谢谢

====新====

@Jon Skeet,@dbemerlin,感谢您的回复。我猜想 Tcp 握手需要一些时间工具。

所以我做了实验 3。

我将 HttpListener 设置为服务器并使用 WebClient 发送/接收,数据大小完全相同。每次我使用新的 WebClient 在英国和日本之间发送/接收时。

结果为 0.86(500 次循环的平均值,即发送/接收)。

我假设 WebClient / HttpLisener 本身就是 Tcp,对吧?在我的实验中,它们如何比原始 TcpClient/TcpListener 更快??

再次感谢

【问题讨论】:

  • 要么您的 WebClient 使连接保持打开状态和/或使用流水线,要么 TcpClient/TcpListener 类很慢并且不用于 HttpListener/WebClient 类,但微软不太可能(反对所有谣言)做得很好。使用 Wireshark 检查英国和日本之间的真实情况。另外:网络连接(尤其是远距离)可能会根据一天中的时间而产生不同的连接速度,因此请确保重复之前的实验。

标签: c# connection latency tcpclient


【解决方案1】:

这并不特别令人惊讶,但这并不是创建对象的成本——而是建立 TCP 连接、握手等的成本。

如果您可以通过单个连接完成大量工作,那么这比每次都建立一个新连接更有效。用现实世界的话来说,考虑一下两个人之间的电话交谈。

高效场景:你拨打号码,他们接听,你说话,他们回复,你说话,他们回复等等。

低效场景:你拨号码,他们接听,你说话,他们回复,你挂断。然后您立即再次拨打该号码,他们接听,您通话,他们回复,您挂断等。

想象一下在现实中做后者!你很快就会发疯的......

编辑:默认情况下,WebClient 将保持对 Web 服务器的挂起连接。如果您强制重置连接(基本上禁用 KeepAlive),那么您将再次看到缓慢的行为。

【讨论】:

  • 我在 WebClient 中没有看到 KeepAlive 的任何属性。我可以禁用它并重试吗?
【解决方案2】:

每个 TCP 连接在创建时都需要一个握手(公平的三向握手,不确定 atm),这意味着即使没有发送数据但一个包被发送到目标,另一个包也会被发回 - 如果它是三次握手 - 第三次被发送到目标。

我们假设一个包裹从英国到日本需要 100 毫秒。这意味着每个“tcpClient.Connect()”需要 300 毫秒而不发送任何数据。您的正常发送和接收包括一个包裹发送到目的地,另一个包裹返回,总共需要 200 毫秒。关机(如果它是干净的)需要另外 100 毫秒。

这导致发送消息需要 600 毫秒,而如果您保持连接正常则需要 200 毫秒,因为您将保存握手并关机。

【讨论】:

    猜你喜欢
    • 2011-05-20
    • 2020-08-30
    • 1970-01-01
    • 1970-01-01
    • 2011-01-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多