0

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 = trueand 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 SocketExceptions 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.Streamand setting writeTimeout results in an error telling me that writeTimeout is not supported on the current stream.

Remy
  • 4,843
  • 5
  • 30
  • 60
  • My educated guess is you have an inner exception of type `SocketException` somewhere down the stack. It's an network operation, regardless of whether you are running both client and server locally. The connection is being closed so my guess is this might be a timeout on the client side of things. – JuanR Dec 17 '18 at 15:06
  • Probably it is the response time of getting the IP from the DNS server. – jdweng Dec 17 '18 at 15:07
  • Thanks for the replies, What would be the best way to check if it is the response time or a timeout happening? Can i set a timeout in the header or something similiar to test this? – Remy Dec 17 '18 at 15:09
  • Please take a moment to read this: https://msdn.microsoft.com/en-us/library/ms847613.aspx. Your code should be handling this as it can (and most likely will) happen for a variety of reasons. That being said, this is more of a concern on the client side. The server side simply handles the exception (and logs it), but the client side needs to take any steps needed to recover (e.g. resend the request). – JuanR Dec 17 '18 at 15:14

0 Answers0