为什么TcpClient与构造函数中的参数连接速度较慢?

时间:2013-08-22 20:59:16

标签: c# .net sockets tcpclient

我遇到System.Net.Sockets.TcpClient的问题。

一个简单的测试应用程序只是打开一个连接,发送一些数据,然后关闭。另一端有一个简单的服务器,性能很好。

代码看起来像这样:

var client = new TcpClient("localhost", 1234);
using (var stream = client.GetStream())
using (var writer = new StreamWriter(stream))
{
    writer.Write("foo");
    writer.flush();
}
client.Close();

它工作正常,但我注意到单元测试正在进行>运行1000ms。当我把它放在一个叫10次的循环中时,它是> 10,000ms。

在客户端和服务器上进行了几个小时的调试后,我发现它很慢 解决方法是更改​​代码:

var client = new TcpClient("localhost", 1234);

到此:

var client = new TcpClient();
client.Connect("localhost", 1234);

这一切都有所不同。一次通过大约需要10ms,10次通过不到100ms。

WHY ???

2 个答案:

答案 0 :(得分:4)

来自http://msdn.microsoft.com/en-us/library/115ytk56(v=vs.110).aspx

"如果启用了IPv6并且调用了TcpClient(String,Int32)方法以连接到解析为IPv6和IPv4地址的主机,则将首先尝试在IPv4地址之前连接到IPv6地址。如果主机没有监听IPv6地址,这可能会延迟建立连接的时间。"

我不确定默认构造函数为什么也不这样做(我原本以为你必须使用带有AddressFamily的构造函数并在连接之前指定IPv4)但显然它没有&#39 ;吨

答案 1 :(得分:-1)

你会喜欢这个答案。我不知道,因为对我来说没有意义。

使用Reflector,v.2程序集中的默认ctor是

public TcpClient() : this(AddressFamily.InterNetwork)
{
    if (Logging.On)
    {
        Logging.Enter(Logging.Sockets, this, "TcpClient", (string) null);
    }
    if (Logging.On)
    {
        Logging.Exit(Logging.Sockets, this, "TcpClient", (string) null);
    }
}

如果您没有启用日志记录,上面的代码几乎是无操作

第二个ctor(字符串主机名,int端口)完成所有这些以及更多当然,但是“more”的一部分是对第二个示例中使用的相同TcpClient.Connect()方法的调用。即,在两种情况下执行的代码几乎相同。我挖了进去,因为我想知道MS代码怎么会有这么奇怪的问题 - 最好的我可以通过观察这个问题告诉他们,他们没有一个奇怪的问题。我以为我可能会看到一些奇怪的DNS查找问题,或类似但没有骰子。

连接套接字几乎可以保证减慢速度,但我希望这最多可能需要大约100或200毫秒,除非你有一个非常糟糕的Internet连接,DNS服务器或代理服务器。但是我发现在你的2个案例中只有1个例外会导致明显不同的行为。您的示例并未完整显示您的using子句可能有何不同。如果套接字上存在触发缓慢行为的清理代码,那么您的2个示例可能会有所不同。