【问题标题】:SharpSVN connection rate limit to localhost?SharpSVN 对本地主机的连接速率限制?
【发布时间】: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


【解决方案1】:

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

您可以输入C:\Windows\System32\drivers\etc\hosts 类似:

127.0.0.1 localhost-ipv4

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

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

Apache 网络服务器也可以这样做:

Listen 0.0.0.0:80
Listen [::]:80

【讨论】:

  • 感谢您的提示。我怀疑我们是否可以要求我们软件的用户弄乱 Windows 内部主机文件(他们中的大多数都在公司环境中,不一定具有管理员权限)。但是记录 SVN 服务器应该在启用 IPV6 的环境中更喜欢 IPV6 的事实是一个好主意。虽然我担心有些网络主机可以解析 IPv6 地址,但路由器不传递 IPv6 数据包......
猜你喜欢
  • 2014-01-23
  • 1970-01-01
  • 2019-11-17
  • 2014-01-23
  • 2011-01-09
  • 1970-01-01
  • 1970-01-01
  • 2012-10-23
  • 1970-01-01
相关资源
最近更新 更多