C#: Simple HTTP server - c#

Based on MS example code I wrote a simple HTTP server.
listener = new HttpListener();
listener.Prefixes.Add("http://*:8000/");
while (true)
{
listener.Start();
HttpListenerContext context = listener.GetContext();
HttpListenerRequest request = context.Request;
// Obtain a response object.
HttpListenerResponse response = context.Response;
listener.Stop();
}
It seems that at each loop must start with "listenet.Start" and end with "listener.Stop"
When I used only "listener.Start" before the loop, I stopped getting messages from a working Angular client after 2 messages.
Can you please tell why ?
Thank you,
Zvika

Related

Starting a web server using C# and .net in Visual Studio

I am using the below code to start a web server that should be open to listen always but it is executing only once, I am deploying this in AKS - the container is not staying in running state, it is exiting after completing the job i.e., printing the response.
Please help me understand where I am doing wrong or my understanding itself is not right.
May be this is not the right piece of code to use if I want the container to be always running as a web server that listens to requests from other apps in the project.
string baseAddress = "http://localhost:9000/";
// Start OWIN host
using (WebApp.Start<Startup>(url: baseAddress))
{
// Create HttpClient and make a request to api/values
HttpClient client = new HttpClient();
var response = client.GetAsync(baseAddress + "api/values").Result;
System.Console.WriteLine(response);
System.Console.WriteLine(response.Content.ReadAsStringAsync().Result);
System.Console.ReadLine();
}
If your code is already working for once. Thats should be help for loop
while(true){
var response = client.GetAsync(baseAddress + "api/values").Result;
System.Console.WriteLine(response.Content.ReadAsStringAsync().Result);
}
If you want to listen incoming http requests, try something like that with HttpListener:
var listener = new HttpListener();
listener.Prefixes.Add("http://*:9000/api/values");
listener.Start();
while (true)
{
HttpListenerContext context = listener.GetContext();
HttpListenerRequest request = context.Request;
// do something here with request
// default OK response
context.Response.StatusCode = 200;
context.Response.OutputStream.Write(Array.Empty<byte>(), 0, 0);
context.Response.Headers.Add("Access-Control-Allow-Origin", "*");
context.Response.Close();
}

Http Client sents request twice

I'm using an http client and an http server(listener)
In some cases when i'm having big delay-traffic in my network, http client sends request but it nevers takes a response from http listener.As a result i'm trying to resend my request to server. But, server already has took previous one request and re-runs the new one. In this case, server runs my request twice.
httplistener
HttpListener listener;
Thread t;
private void Form1_Load(object sender, EventArgs e)
{
t = new Thread(new ThreadStart(MyThreadMethod));
t.IsBackground = true;
listener = new HttpListener();
listener.Prefixes.Add("http://192.168.0.214:8282/");
listener.Start();
t.Start();
// label1.Text = "Opened";
}
void MyThreadMethod()
{
while (true)
{
IAsyncResult result = listener.BeginGetContext(new AsyncCallback(ListenerCallback), listener);
result.AsyncWaitHandle.WaitOne();
}
}
public void ListenerCallback(IAsyncResult result)
{
HttpListener listener = (HttpListener)result.AsyncState;
HttpListenerContext context = listener.EndGetContext(result);
string methodName = Convert.ToString(context.Request.Url);
//Here is my code
string Response = "OK";
HttpListenerResponse response = context.Response;
string responseString = Convert.ToString(Response);
byte[] buffer = System.Text.Encoding.UTF8.GetBytes(responseString);
response.ContentLength64 = buffer.Length;
System.IO.Stream output = response.OutputStream;
output.Write(buffer, 0, buffer.Length);
output.Close();
}
And here is my httpClient
HttpClient client = new HttpClient();
var content = new StringContent("my Data", Encoding.UTF8, "application/json");
var result = client.PostAsync("http://192.168.0.214:8282/", content).Result;
How can i prevent, when i'm having big delay_ms in my network, http listener running twice my requests?
This is a very common issue for distributed applications. You make a request, someone gets it, sometimes complete the request sometimes can not. Furthermore, sometimes you get the response and sometimes not. To deal with such situations, the rule of thumb is "your commands/requests should be idempotent". I mean, even if you send a request/command several times to a service, the result should not change and the command should only be executed only once. Accomplishing this sometimes can be very complicated but for simple scenarios you can simply accomplish this by adding a command id to your requests and a command log to your server. When server receives the request, it first checks whether this command already executed. If it was executed before, it returns the same success response, otherwise runs the command.

HttpListner not listening

I am trying to check if there is an ajax request to a particular url and if yes, then I am trying to add a cookie to the request.
But my HttpListner is listening only for localhost. If I try to give any other url, it is not listening.
I have turned off my firewall also but still the same issue.
Please tell me where I am making a mistake.
Below is my code:
class Program
{
static void Main(string[] args)
{
HttpListener listner = new HttpListener();
listner.Prefixes.Add("<my url>");//For example, https://www.google.co.in/
listner.Start();
HttpListenerContext context = listner.GetContext();
HttpListenerRequest request = context.Request;
WebRequest webReq = WebRequest.Create(request.Url);
//Copying the headers
System.Collections.Specialized.NameValueCollection headers = request.Headers;
for (int i = 0; i < headers.AllKeys.Length; i++)
{
if (!WebHeaderCollection.IsRestricted(headers.AllKeys[i]))
{
webReq.Headers.Add(headers.AllKeys[i], headers[headers.AllKeys[i]]);
}
}
webReq.ContentLength = request.ContentLength64;
webReq.ContentType = request.ContentType;
webReq.Headers.Add(HttpRequestHeader.Cookie, "<My Cookie>");
HttpListenerResponse response = context.Response;
WebResponse webResponse = webReq.GetResponse();
webResponse.GetResponseStream().CopyTo(response.OutputStream);
}
}
Whatever prefixes you add to the listener HAVE to resolve to your localhost machine. Make sure that your DNS server correctly resolves the host to the machine where you run your code.
If you are testing this in a development environment and/or don't have control over the DNS server, add an entry to the hosts file that maps whatever host name you want to use to your local machine.
The other thing to watch out for is the port. Make sure nothing else is listening on the port you intend to use.

How to handle pipelined requests with C#?

I need to handle pipelined requests in my C# Mono (Mono version 3.12.1 on Linux) server, but I noticed that the second request in the pipeline is always ignored.
Here's my netcat command to test pipelining:
nc -v localhost 5000 < httppipe.txt
Here's the contents of httppipe.txt:
GET /heartbeat HTTP/1.1
Host: localhost
GET /heartbeat HTTP/1.1
Host: localhost
I'm pretty confident my netcat approach works because I tested it on a Java server successfully. (Meaning I saw 2 responses)
In my C# server, I've tried both GetResult and GetResultAsync. The code with GetResultAsync is basically pulled right from the MSDN example. It looks like this:
this.Listener = new HttpListener();
this.Listener.Prefixes.Add(uriPrefix);
this.Listener.BeginGetContext(new AsyncCallback(ListenerCallback),this.Listener);
public static void ListenerCallback(IAsyncResult result)
{
HttpListener listener = (HttpListener) result.AsyncState;
// Call EndGetContext to complete the asynchronous operation.
HttpListenerContext context = listener.EndGetContext(result);
listener.BeginGetContext(new AsyncCallback(ListenerCallback), listener);
HttpListenerRequest request = context.Request;
// Obtain a response object.
HttpListenerResponse response = context.Response;
// Construct a response.
string responseString = "<HTML><BODY> Hello world!</BODY></HTML>";
byte[] buffer = System.Text.Encoding.UTF8.GetBytes(responseString);
// Get a response stream and write the response to it.
response.ContentLength64 = buffer.Length;
System.IO.Stream output = response.OutputStream;
output.Write(buffer,0,buffer.Length);
// You must close the output stream.
output.Close();
}
EDIT: Also tried on Mono 4.0 on Linux to no avail.

HttpListener problems: Each HTTP request results in two contexts returned by HttpListener

I have been putting together a little embedded HTTP server in a windows service app that listens for updates coming from other devices on the network that speak HTTP.
For each HTTP request, the code that processes the request/response is executed twice, I expect it to run only once. I tried the code using the AsyncGetContext method and using the synchronous version GetContext - the end result is the same.
Code
public void RunService()
{
var prefix = "http://*:4333/";
HttpListener listener = new HttpListener();
listener.Prefixes.Add(prefix);
try
{
listener.Start();
_logger.Debug(String.Format("Listening on http.sys prefix: {0}", prefix));
}
catch (HttpListenerException hlex)
{
_logger.Error(String.Format("HttpListener failed to start listening. Error Code: {0}", hlex.ErrorCode));
return;
}
while (listener.IsListening)
{
var context = listener.GetContext(); // This line returns a second time through the while loop for each request
ProcessRequest(context);
}
listener.Close();
}
private void ProcessRequest(HttpListenerContext context)
{
// Get the data from the HTTP stream
var body = new StreamReader(context.Request.InputStream).ReadToEnd();
_logger.Debug(body);
byte[] b = Encoding.UTF8.GetBytes("OK");
context.Response.StatusCode = 200;
context.Response.KeepAlive = false;
context.Response.ContentLength64 = b.Length;
var output = context.Response.OutputStream;
output.Write(b, 0, b.Length);
output.Close();
context.Response.Close();
}
Is there anything obvious that I am missing, I have run out of ideas to track down the issue.
Ok, the issue was I was using a web browser to test the HTTP connection and by default a web browser also sends a request for favicon.ico. So two requests were actually coming across. Thank you to #Inuyasha for suggesting I check things out with Wireshark.

Categories

Resources