views:

53

answers:

1

So, for a bit of background : This class is created to accept and respond to calls made remotely in an HTTP format.

The problem is when the method of the request is POST, sometimes the request is processed correctly, but most of the times the class just ends up being irresponsive. Also, the line "Debug1" and "Debug2" are never written to the console, even when the request is processed correctly. The line "Debug3" appears only when the request is processed correctly.

I know this will probably look messy, C# is only a hobby for me, and I'm learning :) Thanks for spending some time to go through this code!

Here is the code:

class WebServer
{
    private TcpListener myListener;

    public WebServer(int port)
    {
        //Threading the listener
        try
        {
            myListener = new TcpListener(IPAddress.Any, port) ;
            myListener.Start();

            Thread th = new Thread(new ThreadStart(StartListen));
            th.Start() ;
        }
        catch(Exception e)
        {
            Logs.Add("WebServer|An Exception Occurred while Listening :" +e.ToString());
        }
    }
    private void StartListen()
    {
        int iStartPos = 0;
        string sHttpVersion;
        string sResponse = "";
        string sCode = " 200 OK";

        while(true)
        {
            //Accept a new connection
            Socket mySocket = myListener.AcceptSocket();
            if(mySocket.Connected)
            {
                Byte[] bReceive = new Byte[1024];
                int i = mySocket.Receive(bReceive,bReceive.Length,SocketFlags.None);
                string sBuffer = Encoding.ASCII.GetString(bReceive).TrimEnd('\0');

                iStartPos = sBuffer.IndexOf("HTTP",1);
                sHttpVersion = sBuffer.Substring(iStartPos,8); //http version (ex: "HTTP/1.1")

                if (sBuffer.StartsWith("GET / "))
                {
                    Logs.Add("WebServer|Connected:" + mySocket.RemoteEndPoint.ToString());
                    sResponse = ArrayToJson();
                }
                else if (sBuffer.StartsWith("POST"))
                {
                    Console.WriteLine("Debug1");

                    //This is a POST request, so more data is waiting to be retreived...  
                    bReceive = new Byte[2048];
                    i = mySocket.Receive(bReceive,bReceive.Length,SocketFlags.None);
                    sBuffer = Encoding.ASCII.GetString(bReceive).TrimEnd('\0');

                    Console.WriteLine("Debug2");

                    //Parsing the request
                    string[] sParams = sBuffer.Split(',');
                    Console.WriteLine(sParams.Length);
                    Console.WriteLine("Debug3: {0} - {1} - {2} - {3} - {4}", sParams[0], sParams[1], sParams[2], sParams[3], sParams[4]);

                    //I do what needs to be done here

                    Logs.Add("WebServer|BotStartRequest:" + mySocket.RemoteEndPoint.ToString());
                    sResponse = "Accepted";
                }

                //Sending response and closing socket
                SendHeader(sHttpVersion, "text/html", sResponse.Length, sCode, ref mySocket);
                SendToBrowser(sResponse, ref mySocket);
                mySocket.Close();
            }
        }
    }
}

}

+4  A: 

Implementing HTTP/1.1 is not a simple task. The basic protocol looks quite simple, but it's really hard to get even a minimal server implementation right: You have at least to think about persistent connections, in the case of POST of the Expect: 100-continue header, correctly parsing the header, and much more.

I strongly recommend you have a look at existing libraries/code. For example, the HttpListener class is built into the .NET Framework and probably already provides all you'll ever need.

If you really want to implement a server from scratch, have a look at Microsoft Cassini, a simple HTTP server written in C# licensed under Ms-PL.

dtb
Thanks, if I can't make it work, that's probably what I'll end up doing. But it is because my use of it is so simple that I wanted to make it my own, and not use an existing library.
Ben