Create your own Web Server using C#

The Code (2)

We also need to identify the Mime type, using the file extension supplied by the user

public string GetMimeType(string sRequestedFile)
{


    StreamReader sr;
    String sLine = "";
    String sMimeType = "";
    String sFileExt = "";
    String sMimeExt = "";

    // Convert to lowercase
    sRequestedFile = sRequestedFile.ToLower();

    int iStartPos = sRequestedFile.IndexOf(".");

    sFileExt = sRequestedFile.Substring(iStartPos);

    try
    {
        //Open the Vdirs.dat to find out the list virtual directories
        sr = new StreamReader("data\\Mime.Dat");

        while ((sLine = sr.ReadLine()) != null)
        {

            sLine.Trim();

            if (sLine.Length > 0)
            {
                //find the separator
                iStartPos = sLine.IndexOf(";");

                // Convert to lower case
                sLine = sLine.ToLower();

                sMimeExt = sLine.Substring(0,iStartPos);
                sMimeType = sLine.Substring(iStartPos + 1);

                if (sMimeExt == sFileExt)
                    break;
            }
        }
    }
    catch (Exception e)
    {
        Console.WriteLine("An Exception Occurred : " + e.ToString());
    }

    if (sMimeExt == sFileExt)
        return sMimeType; 
    else
        return "";
}

Now we will write the function, to build and sends header information to the browser (client)

public void SendHeader(string sHttpVersion, 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 + sHttpVersion + 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); 

    SendToBrowser( bSendData, ref mySocket);

    Console.WriteLine("Total Bytes : " + iTotBytes.ToString());

}

The SendToBrowser function sends information to the browser. This is an overloaded function.


public void SendToBrowser(String sData, ref Socket mySocket)
{
    SendToBrowser (Encoding.ASCII.GetBytes(sData), ref mySocket);
}


public void SendToBrowser(Byte[] bSendData, ref Socket mySocket)
{
    int numBytes = 0;
    try
    {
        if (mySocket.Connected)
        {
            if (( numBytes = mySocket.Send(bSendData,
                     bSendData.Length,0)) == -1)
                Console.WriteLine("Socket Error cannot Send Packet");
            else
            {
                Console.WriteLine("No. of bytes send {0}" , numBytes);
            }
        }
        else
            Console.WriteLine("Connection Dropped....");
    }
    catch (Exception  e)
    {
        Console.WriteLine("Error Occurred : {0} ", e );
    }
}

We now have all the building blocks ready, now we will delve into the key function of our application.


public void StartListen()
{

    int iStartPos = 0;
    String sRequest;
    String sDirName;
    String sRequestedFile;
    String sErrorMessage;
    String sLocalDir;
    String sMyWebServerRoot = "C:\\MyWebServerRoot\\";
    String sPhysicalFilePath = "";
    String sFormattedMessage = "";
    String sResponse = "";


    while(true)
    {
        //Accept a new connection
        Socket mySocket = myListener.AcceptSocket() ;

        Console.WriteLine ("Socket Type " +     mySocket.SocketType ); 
        if(mySocket.Connected)
        {
            Console.WriteLine("\nClient Connected!!\n==================\n
             CLient IP {0}\n", mySocket.RemoteEndPoint) ;


            //make a byte array and receive data from the client 
            Byte[] bReceive = new Byte[1024] ;
            int i = mySocket.Receive(bReceive,bReceive.Length,0) ;


            //Convert Byte to String
            string sBuffer = Encoding.ASCII.GetString(bReceive);


            //At present we will only deal with GET type
            if (sBuffer.Substring(0,3) != "GET" )
            {
                Console.WriteLine("Only Get Method is supported..");
                mySocket.Close();
                return;
            }


            // Look for HTTP request
            iStartPos = sBuffer.IndexOf("HTTP",1);


            // Get the HTTP text and version e.g. it will return "HTTP/1.1"
            string sHttpVersion = sBuffer.Substring(iStartPos,8);


            // Extract the Requested Type and Requested file/directory
            sRequest = sBuffer.Substring(0,iStartPos - 1);


            //Replace backslash with Forward Slash, if Any
            sRequest.Replace("\\","/");


            //If file name is not supplied add forward slash to indicate 
            //that it is a directory and then we will look for the 
            //default file name..
            if ((sRequest.IndexOf(".") <1) && (!sRequest.EndsWith("/")))
            {
                sRequest = sRequest + "/"; 
            }
            //Extract the requested file name
            iStartPos = sRequest.LastIndexOf("/") + 1;
            sRequestedFile = sRequest.Substring(iStartPos);


            //Extract The directory Name
               sDirName = sRequest.Substring(sRequest.IndexOf("/"), 
                       sRequest.LastIndexOf("/")-3);

The code is self-explanatory. It receives the request, converts it into string from bytes then look for the request type, extracts the HTTP Version, file and directory information.

You might also like...

Comments

About the author

Imtiaz Alam United States

Imtiaz Alam is a Senior Developer, currently residing in Phoenix, Arizona. He has more than five years of development experience in developing Mirosoft based Solution.

Interested in writing for us? Find out more.

Contribute

Why not write for us? Or you could submit an event or a user group in your area. Alternatively just tell us what you think!

Our tools

We've got automatic conversion tools to convert C# to VB.NET, VB.NET to C#. Also you can compress javascript and compress css and generate sql connection strings.

“Most software today is very much like an Egyptian pyramid with millions of bricks piled on top of each other, with no structural integrity, but just done by brute force and thousands of slaves” - Alan Kay