Я установил 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 не поддерживается в текущем потоке.