I set up an HttpListener that listens to file requests over the localhost. I initialize the Listener as follows:
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!");
}
When a file has been requested A check is performed for wether or not the file exists on the local storage already. If it doesn't the file gets requested and downloaded from the server to the local storage (this works).
If the file is on local storage (or just downloaded to the local storage) It gets read back to the response
of the HttpsListenerContext
using filestream and 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);
}
Most of the time this works as intended, but about 5% of the time i get the error System.IO.IOException: Unable to write data to the transport connection: Connection reset by peer. ---> System.Net.Sockets.SocketException: Connection reset by peer.
It seems to happen at random, not on any specific files or after a certain amount of time.
I tried fiddling around with the Response
settings like KeepAlive = true
and setting the ProtocolVersion
to HttpVersion.Version11
. But this changed nothing.
I found this answer on SO which suggests it may be blocked by the firewall, but since it only happens on occassion, and it is all over local this seems unlikely to me. Or that the connection to the target machine (peer) is unaivalable/closed. But I am unsure how that can happen if its all done locally.
Since the error also contains ---> System.Net.Sockets.SocketException: Connection reset by peer.
I tried to see if there are any SocketException
s in the ecapsulating try/catch
, but this passes and goes to the IOException
catch.
I am using Unity with the .net 4.x api comppatability level and .Net 4.x Eqvuialent scripting runtime version. using the IL2CPP scripting backend.
The prominent build target is Android which is happens on most frequent, but not exclusively. It also happens within the Unity editor (2019), albeit less frequent
EDIT: as per comments i have been trying to find out wether or not it is a time-out issue. To do this i've been logging the time it took to process, and from the results it seems unlikely to me it is because of a timeout. As sometimes a request that completes normally takes longer than a request that fails. Or is the timeout set dynamically by the socket?
I have tried setting TimeoutManager to allow for longer idle times, but i get NotImplementedException
when i do this. passing the OutputStream to System.UI.Stream
and setting writeTimeout
results in an error telling me that writeTimeout is not supported on the current stream.