SharpSVN对localhost的连接速率限制?

时间:2011-07-13 13:37:19

标签: c# .net svn connection sharpsvn

我们使用SharpSVN以编程方式访问SVN存储库。现在我们遇到的问题是,通过svn://或http:// urls访问本地存储库非常慢 - 每次访问都需要至少一秒,而我们的应用程序需要获取一堆属性和目录列表。

我们可以在两台不同的机器上重现这个问题,它们都是Windows 7 32位并且位于同一个域中。 SVN服务器是http:// urls的VisualSVN 2.1.9和svn:// urls的CollabNet 1.6.17。通过“localhost”和主机名显示连接。它出现在我们的C#应用​​程序中,以及使用IronPython和调用SharpSvn svn.exe命令的小型测试平台应用程序。

访问远程存储库(Linux和Windows XP服务器)时访问时不会发生此问题 - 此处,每次访问时间介于0.01和0.08秒之间,这是由于网络延迟所致。通过file:// urls访问本地存储库或通过CollabNet中的“native”svn命令行工具访问存储库时,也不会发生此问题。

现在我的问题是:Windows 7或.NET或SharpSVN是否有一些仅适用于localhost连接的内置限制?

(另外:我现在发现,当使用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));
        }
    }
}

所以这个问题似乎不是特定于颠覆的。)

Addition2:在Windows的Mono 2.10下运行客户端时,问题不会出现。所以它似乎特定于.NET框架。

补充3:这似乎是与IPv6相关的问题。服务器仅侦听IPv4,但主机名也解析为IPv6。现在似乎OS代码在内部尝试IPv6连接,并在获得连接重置后,等待1秒后再回退到IPv4。每次连接尝试都会重复此游戏。 http://msdn.microsoft.com/en-us/library/115ytk56.aspx记录了TcpClient的内容(感谢MSDN论坛中的Andreas Johansson提示!),似乎Apache内部使用的APR使用了类似的机制。

1 个答案:

答案 0 :(得分:2)

添加3也是您问题的解决方案。要解决此问题,请使DNS / hosts文件仅解析为IPv4地址,或使IPv6服务器正常工作。

您可以输入C:\Windows\System32\drivers\etc\hosts之类的内容:

127.0.0.1 localhost-ipv4

然后使用该名称进行连接。

您还可以使svnserve侦听IPv6地址。快速搜索svnserve选项[显示] [1]它默认为IPv6,因此其启动参数可能是--listen-host。尝试删除它,或者当它不存在时强制它在IPv6上运行。

Apache Webserver也可以这样做:

Listen 0.0.0.0:80
Listen [::]:80