I wanted to set up a very basic webserver in C# on my server (Linux version 2.6.32-5-vserver-amd64 (Debian 2.6.32-48).
The server is in my my city and near zero overhead functionality like displaying 7 lines of html via Apache2 or Tomcat 8 takes ~15ms (DNS 1ms, Connecting 4ms, Sending 1ms, Waiting 6ms, Receiving 4ms).
When running my minimal c# webserver on that server the Receiving phase lasts 60ms!
I tried it out on my local computer in .net framework and mono as well and it always takes just a single millisecond at worst.
By testing a bit I found out that if I don't send any data via context.Response.OutputStream.Write(...) it's even faster than Apache2 or Tomcat, with Receiving going down to 0ms!
Sending headers doesn't make it slower and works fine.
Mono 3.0.6 is running on the server and I used 3.0.6 on my Windows PC for testing.
It boils down to the question:
Why is OutputStream.Write(...) so slow on my server and how do I fix it?
Here is the C# code:
internal class Program
{
private static void Main(string[] args)
{
System.Net.HttpListener listener = new System.Net.HttpListener();
listener.Prefixes.Add("http://domain.tld:7777/");
//listener.Prefixes.Add("http://localhost:7777/");
//listener.Prefixes.Add("http://127.0.0.1:7777/");
listener.Start();
while (true)
{
System.Net.HttpListenerContext context = listener.GetContext();
System.Threading.Tasks.Task.Factory.StartNew(() => { ProcessRequest(context); });
}
}
private static void ProcessRequest(System.Net.HttpListenerContext context)
{
System.Net.HttpListenerResponse response = context.Response;
response.ContentType = "text/html";
byte[] bytes = GetBytes("Testtext");
response.OutputStream.Write(bytes, 0, bytes.Length); // this line makes the request 60ms slower!
context.Response.Headers.Add("headerName", "This is the headervalue");
response.Close();
}
private static byte[] GetBytes(string str)
{
byte[] bytes = new byte[str.Length * sizeof(char)];
System.Buffer.BlockCopy(str.ToCharArray(), 0, bytes, 0, bytes.Length);
return bytes;
}
}
I found a solution, or rather workaround:
If I use
response.Close(bytes, bool); // doesn't matter whether boolean is true or false
and don't write to the Stream at all it's blazingly fast. Fine with me but I still don't get it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With