6

This might be a piece of cake for any experienced C# developer

What you see here is a sample Asynchronous webserver

using System;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Threading;

namespace SimpleServer
{
    class Program
    {
        public static void ReceiveCallback(IAsyncResult AsyncCall)
        {            
            System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
            Byte[] message = encoding.GetBytes("I am a little busy, come back later!");            
            Socket listener = (Socket)AsyncCall.AsyncState;
            Socket client = listener.EndAccept(AsyncCall);
            Console.WriteLine("Received Connection from {0}", client.RemoteEndPoint);
            client.Send(message);
            Console.WriteLine("Ending the connection");
            client.Close();
            listener.BeginAccept(new AsyncCallback(ReceiveCallback), listener);
        }

    public static void Main()
    {
        try
        {
            IPAddress localAddress = IPAddress.Parse("127.0.0.1");
            Socket listenSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            IPEndPoint ipEndpoint = new IPEndPoint(localAddress, 8080);
            listenSocket.Bind(ipEndpoint);
            listenSocket.Listen(1);
            listenSocket.BeginAccept(new AsyncCallback(ReceiveCallback), listenSocket);
            while (true)
            {                    
                Console.WriteLine("Busy Waiting....");
                Thread.Sleep(2000);
            }                
        }
        catch (Exception e)
        {
            Console.WriteLine("Caught Exception: {0}", e.ToString());
        }
    }
}

I downloaded this from the web, in order to have a basic model to work on.

Basically what I need to do is run this webserver as a process in a computer. It will be listening to por 8080 all the time, and when a client computer sends a request, this server will process some data and send back a result as a string.

I created a small project with this code (which is functional as is), but when it executes the line

client.Send(message);

all I get is an error in the browser, or at most a blank page

I suspect I need to define the HTTP headers to send with the (message), but I have been searching the web on this with no luck

Anyone willing to help?

Thanks!

msarchet
  • 15,104
  • 2
  • 43
  • 66
jprealini
  • 349
  • 4
  • 17

1 Answers1

4

You need something like this

HTTP/1.1 200 OK
Server: My Little Server
Content-Length: [Size of the Message here]
Content-Language: en
Content-Type: text/html
Connection: close

[Message]

If you send this hole block of data it should work correctly.

Edit:

You can use this Method:

    public static void SendHeader(string sMIMEHeader, int iTotBytes, string sStatusCode, ref Socket mySocket)
    {
        String sBuffer = "";
        // if Mime type is not provided set default to text/html
        if (sMIMEHeader.Length == 0)
        {
            sMIMEHeader = "text/html";  // Default Mime Type is text/html
        }
        sBuffer = sBuffer + "HTTP/1.1" + sStatusCode + "\r\n";
        sBuffer = sBuffer + "Server: cx1193719-b\r\n";
        sBuffer = sBuffer + "Content-Type: " + sMIMEHeader + "\r\n";
        sBuffer = sBuffer + "Accept-Ranges: bytes\r\n";
        sBuffer = sBuffer + "Content-Length: " + iTotBytes + "\r\n\r\n";
        Byte[] bSendData = Encoding.ASCII.GetBytes(sBuffer);
        mySocket.Send(Encoding.ASCII.GetBytes(sBuffer),Encoding.ASCII.GetBytes(sBuffer).Length, 0);
        Console.WriteLine("Total Bytes : " + iTotBytes.ToString());
    }

And in your Main()-Method you should replace

Byte[] message = encoding.GetBytes("I am a little busy, come back later!");

with

string messageString = "I am a little busy, come back later!";
Byte[] message = encoding.GetBytes(messageString);

and then insert

// Unicode char may have size more than 1 byte so we should use message.Length instead of messageString.Length
SendHeader("text/html", message.Length, "202 OK", ref client);

before

client.Send(message);

That's all.

haver
  • 3
  • 1
  • 3
Tokk
  • 4,499
  • 2
  • 31
  • 47
  • Thanks for the tip! I have been googling a bit, but I can't find a way to generate the HTTP headers... could you give me a link or an example based on the code I pasted? Thanks again! – jprealini Mar 09 '11 at 17:14
  • 1
    Working on it. Funny Fact: I copied your code, compiled it, and it works :-D – Tokk Mar 09 '11 at 18:12
  • Wow, great! Another Funny Fact: I had a method similar to this in another test project I was working on, and managed to do this almost exactly as you describe it here, and it worked PERFECTLY... A million thanks... I think I still can't assign point or stuff like that, but you should know I would be glad to give you some if I could... Thanks! – jprealini Mar 09 '11 at 20:34
  • ha, ha!! That's what I call a win-win relationship... ;) – jprealini Mar 10 '11 at 11:51