IOException при записи в файловый поток из локального файла - PullRequest
0 голосов
/ 17 декабря 2018

Я установил HttpListener, который слушает запросы файлов через локальный хост.Я инициализирую прослушиватель следующим образом:

public HTTPRequestListener(ServerManager servermanager)
{
    this.serverManager = servermanager;
    listener = new HttpListener();
    listener.Prefixes.Add("http://" + GetLocalIPAddress() + ":50003/");

    listener.Start();
    httpListenerThread = new Thread(RunListener);
    httpListenerThread.Start();
}

/// <summary>
/// Returns the local ip, courtesy of https://stackoverflow.com/a/6803109/8628766
/// </summary>
public static string GetLocalIPAddress()
{
    var host = Dns.GetHostEntry(Dns.GetHostName());
    foreach (var ip in host.AddressList)
    {
        if (ip.AddressFamily == AddressFamily.InterNetwork)
        {
            return ip.ToString();
        }
    }
    throw new Exception("No network adapters with an IPv4 address in the system!");
}

Когда файл был запрошен. Проверка выполняется для влажной или нет файл уже существует в локальном хранилище.Если это не так, файл запрашивается и загружается с сервера в локальное хранилище (это работает).

Если файл находится в локальном хранилище (или просто загружается в локальное хранилище), он возвращается кresponse из HttpsListenerContext с использованием файлового потока и Response.OutputStream.Write:

 using (FileStream fileStream = new FileStream(ServerManager.persistentDataPath + fileName, FileMode.Open, FileAccess.Read))
 {
     byte[] buffer = new byte[fileStream.Length];
     fileStream.Read(buffer, 0, (int)fileStream.Length);
     context.Response.ContentLength64 = fileStream.Length;
     context.Response.ContentEncoding = Encoding.ASCII;
     context.Response.ContentType = "text/plain; charset=utf-8";
     context.Response.AddHeader("Cache-Control", "no-cache");
     context.Response.OutputStream.Write(buffer, 0, buffer.Length);
 }

Большую часть времени это работает как положено, но примерно в 5% случаев я получаю ошибку System.IO.IOException: Unable to write data to the transport connection: Connection reset by peer. ---> System.Net.Sockets.SocketException: Connection reset by peer.

Кажется, это происходит случайным образом, а не в каких-либо конкретных файлах или через определенное время.

Я попытался поиграться с настройками Response, такими как KeepAlive = true, и установить ProtocolVersion в HttpVersion.Version11.Но это ничего не изменило.

Я нашел этот ответ на SO, который предполагает, что он может быть заблокирован брандмауэром, но так как это происходит только в отдельных случаях, и это везде локально, это кажется маловероятныммне.Или что соединение с целевой машиной (одноранговой) не доступно / закрыто.Но я не уверен, как это может произойти, если все это делается локально.

Поскольку ошибка также содержит ---> System.Net.Sockets.SocketException: Connection reset by peer. Я попытался выяснить, есть ли какие-либо SocketException с в экскапулирующем try/catch, но это проходит и переходит к IOException catch.

Я использую Unity с уровнем совместимости API .net 4.x и версией среды выполнения сценариев .Net 4.x Eqvuialent.используя серверный сценарий IL2CPP.

Основной целью сборки является Android, что происходит чаще всего, но не исключительно.Это также происходит в редакторе Unity (2019), хотя и реже

РЕДАКТИРОВАТЬ: согласно комментариям я пытался выяснить, действительно ли это проблема с тайм-аутом.Для этого я записывал время, которое потребовалось для обработки, и из результатов мне кажется маловероятным, что это из-за тайм-аута.Так как иногда запрос, который завершается, обычно занимает дольше , чем запрос, который не выполняется.Или время ожидания устанавливается динамически сокетом?

Я попытался установить TimeoutManager , чтобы увеличить время простоя, но я получаю NotImplementedException, когда я это делаю.передача OutputStream в System.UI.Stream и установка writeTimeout приводит к ошибке, сообщающей, что writeTimeout не поддерживается в текущем потоке.

...