【发布时间】:2011-07-13 13:37:18
【问题描述】:
我们使用 SharpSVN 以编程方式访问 SVN 存储库。现在我们遇到的问题是通过 svn:// 或 http:// url 访问本地存储库非常慢 - 每次访问至少需要一秒钟,我们的应用程序需要获取一堆属性和目录列表。
我们可以在两台不同的机器上重现这个问题,它们都是 Windows 7 32 位并且在同一个域中。 SVN 服务器是用于 http:// 网址的 VisualSVN 2.1.9 和用于 svn:// 网址的 CollabNet 1.6.17。它显示为通过“localhost”和主机名进行的连接。它出现在我们的 C# 应用程序以及使用 IronPython 的小型测试平台应用程序中,并在调用 SharpSvn svn.exe 命令时出现。
在访问远程存储库(linux 和 windows XP 服务器)时访问时不会发生此问题 - 这里,每次访问时间在 0.01 到 0.08 秒之间,这是由于网络延迟而导致的。通过 file:// url 访问本地存储库或通过 CollabNet 中的“本机”svn 命令行工具访问存储库时,也不会发生此问题。
现在我的问题是:Windows 7 或 .NET 或 SharpSVN 是否有一些仅适用于本地主机连接的内置限制?
(补充:我现在发现这个限制也适用于使用 System.Net.Sockets.TcpClient 通过小型 C# 测试程序进行连接时:
服务器:
using System;
using System.IO;
using System.Net;
using System.Net.Sockets;
namespace TcpSpeedServer
{
class Program
{
public static void Main()
{
Int32 port = 47011;
IPAddress localAddr = IPAddress.Parse("127.0.0.1");
var server = new TcpListener(localAddr, port);
server.Start();
Console.WriteLine("Listening on {0} : {1}", localAddr, port);
ulong count = 0;
// Enter the listening loop.
while(true)
{
using (var client = server.AcceptTcpClient()) {
Console.WriteLine("Connected: {0} {1}!", count, client.Client.RemoteEndPoint);
count += 1;
using (var stream = client.GetStream()) {
using (StreamWriter writer = new StreamWriter(stream))
using (StreamReader reader = new StreamReader(stream))
{
string query = reader.ReadLine();
writer.WriteLine("GET / HTTP/1.0");
writer.WriteLine();
writer.Flush();
}
}
}
}
}
}
}
客户:
using System;
using System.Collections.Generic;
using System.IO;
using System.Net.Sockets;
using System.Threading;
namespace TcpSpeedTest
{
class Program
{
const bool ASYNC = false;
static DateTime s_now;
public static void Main(string[] args)
{
var liste = new List<object>();
s_now = DateTime.Now;
for (int i=0; i < 100; i += 1) {
if (ASYNC)
ThreadPool.QueueUserWorkItem(connect, i);
else
connect(i);
}
Console.WriteLine("outer: " + (DateTime.Now - s_now));
Console.ReadLine();
}
private static void connect(object i)
{
DateTime now = DateTime.Now;
using (TcpClient client = new TcpClient("localhost", 47011))
{
var stream = client.GetStream();
using (StreamWriter writer = new StreamWriter(stream))
using (StreamReader reader = new StreamReader(stream))
{
writer.WriteLine("GET / HTTP/1.0");
writer.WriteLine();
writer.Flush();
string result = reader.ReadLine();
}
}
Console.WriteLine(string.Format("inner: {0} - {1} - {2}", i, DateTime.Now - now, DateTime.Now - s_now));
}
}
}
所以这个问题似乎不是特定于颠覆的。)
补充2:在Mono 2.10 for windows下运行客户端时,没有出现问题。所以它似乎是特定于 .NET 框架的。
Addition3:这似乎是一个与 IPv6 相关的问题。服务器仅侦听 IPv4,但主机名也解析为 IPv6。现在看来,操作系统代码在内部尝试 IPv6 连接,并在连接重置后等待 1 秒,然后再回退到 IPv4。每次连接尝试都会重复这个游戏。 http://msdn.microsoft.com/en-us/library/115ytk56.aspx TcpClient 的文档(感谢来自 MSDN 论坛的 Andreas Johansson 的提示!),似乎 Apache 内部使用的 APR 使用了类似的机制。
【问题讨论】:
-
您是否尝试过使用 Wireshark 或 Micrsoft Network Monitor 分析网络流量?很可能是服务器尝试获取其他用户信息并超时,或类似情况。
-
@Thomas:我不认为服务器会做这样的尝试,因为这也会影响本机 svn.exe。我刚刚尝试了两个使用 TcpClient 和 TcpListener 的小型 C# 测试程序 - 每个连接都有相同的 1 秒延迟。
-
您是否尝试过在测试期间禁用防病毒客户端?
-
我做了,但没有解决问题。
标签: c# .net svn connection sharpsvn