Мы используем SharpSVN для программного доступа к репозиториям SVN.Теперь у нас проблема в том, что доступ к локальным репозиториям через svn: // или http: // urls очень медленный - каждому доступу требуется по крайней мере одна секунда, а нашему приложению нужно получить набор свойств и списков каталогов.
Мы могли бы воспроизвести проблему на двух разных машинах, оба являются 32-разрядными Windows 7 и находятся в одном домене.SVN-серверами являются VisualSVN 2.1.9 для http: // urls и CollabNet 1.6.17 для svn: // urls.Он появляется для соединений через "localhost" и через имя хоста.Он появляется в нашем приложении C #, а также в небольшом тестовом приложении с использованием IronPython и при вызове команды SharpSvn svn.exe.
Эта проблема не возникает при доступе к удаленным репозиториям (как в Linux, так и в WindowsXP server) - здесь каждый доступ составляет от 0,01 до 0,08 с, что ожидается из-за задержки в сети.Проблема также не возникает при доступе к локальным репозиториям через file: // urls или при доступе к репозиториям через "нативные" инструменты командной строки svn из CollabNet.
Теперь мой вопрос: есть ли Windows 7 или .NETили SharpSVN какой-то встроенный лимит, который применяется только к локальным соединениям?
(Дополнение: теперь я обнаружил, что этот лимит также применяется при подключении с помощью небольшой тестовой программы на C # с использованием System.Net.Sockets.TcpClient:
Сервер:
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));
}
}
}
Таким образом, эта проблема, по-видимому, не относится к subversion.)
Добавление 2: При запуске клиентапод Mono 2.10 для windows проблема не появляется.Похоже, что это специфично для .NET Framework.
Добавление 3: Кажется, это проблема, связанная с IPv6.Сервер только прослушивает IPv4, но имя хоста также преобразуется в IPv6.Теперь кажется, что код ОС внутренне пытается установить соединение IPv6 и после сброса соединения ждет 1 секунду, прежде чем вернуться к IPv4.И эта игра повторяется для каждой попытки подключения.http://msdn.microsoft.com/en-us/library/115ytk56.aspx документирует это для TcpClient (спасибо Андреасу Йоханссону из форумов MSDN за подсказку!), И кажется, что APR, используемый Apache внутри, использует аналогичный механизм.