TcpClient的创建是否有很多开销?

时间:2010-02-19 13:07:53

标签: c# connection latency tcpclient

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

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

实验1:

在每个发送/接收循环中,我创建一个全新的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更快?

再次感谢

2 个答案:

答案 0 :(得分:6)

这并不特别令人惊讶,但这并不是创建对象的成本 - 它是设置TCP连接的成本,还有握手等。

如果您可以通过单个连接完成大量工作,那么每次设置新连接的效率更高。用现实世界来说,考虑两个人之间的电话交谈。

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

低效的情况:你拨打数字,他们接听,你说话,他们回复,你挂断。然后你立即再次拨打该号码,他们接听,你说话,他们回复,你挂断等等。

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

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

答案 1 :(得分:1)

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

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

这导致600ms发送消息,相比之下,如果保持连接,则为200ms,然后保存握手并关闭。