我尝试使用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更快?
再次感谢
答案 0 :(得分:6)
这并不特别令人惊讶,但这并不是创建对象的成本 - 它是设置TCP连接的成本,还有握手等。
如果您可以通过单个连接完成大量工作,那么每次设置新连接的效率更高。用现实世界来说,考虑两个人之间的电话交谈。
高效的场景:你拨号码,他们接听,你说话,他们回复,你说话,他们回复等。
低效的情况:你拨打数字,他们接听,你说话,他们回复,你挂断。然后你立即再次拨打该号码,他们接听,你说话,他们回复,你挂断等等。
想象一下在现实中做后者!你很快就会发疯...
编辑:默认情况下,WebClient
将为Web服务器保持挂起连接。如果您强制重置连接(基本上禁用KeepAlive),那么您将再次看到缓慢的行为。
答案 1 :(得分:1)
每个TCP连接在创建时需要握手(空中三次握手,不确定atm),这意味着即使没有数据发送,但是一个包被发送到目标,另一个会被发回 - 如果它是三次握手 - 第三次握手被发送到目标。
一个包裹从英国到日本旅行,我们假设,100毫秒。这意味着每个“tcpClient.Connect()”需要300毫秒而不发送任何数据。你的正常发送&接收包括一个发送到目的地的包裹和另一个包裹,需要总共200毫秒。关机(如果它是一个干净的)需要另外100毫秒。
这导致600ms发送消息,相比之下,如果保持连接,则为200ms,然后保存握手并关闭。