Client/Server Demonstration in C#: Part 2

In this article section we try to create a stand-alone server that responds to their client.

Introduction

In my previous article I demonstrated the client that gets a response from a web server. So, in this article section we try to create a stand-alone server that responds to their client.

Client Server archetecture
Background

In my previous article, I have dealt a few jargons. Moving further, a server is a program to satisfy the needs of the client’s request. It is independent from the number of clients.

In Layman’s World

Suppose you are hosting a website on your local host. So, when a user (or client) asks for a web page, then you need to provide that specific page in the Web Response. Since every Web Hosting Company (Domain Provider) have their built-in servers that handle all these Web Request/Web Response processes.

Procedure

Step 1: Ensure you have added the necessary namespace to your project as in the following:

Using System.IO;
Using System.Net.Sockets;

Step 2: We are creating a server that responds to the client’s request. So, there must be something that reads the Web Request of Clients. For this, TcpListner is there to do our job. So, create an Object of TcpListner and a port number as an argument.

TcpListener listner = new TcpListener(1500);

Here, I have given 1500 as the port number.

It indicates that My Server is accessible by this port (1500) only. You may have a different port number.

Fact: The first 1024 port numbers are reserved for use by the system. You must avoid the first 1024 as your port number.

And, now start the TcpListner.

listner.Start();

Step 3: Start an infinite while loop, and put this code within that.

  while (true)

  {

        Console.WriteLine("Waiting For Connection....");

         TcpClient client = listner.AcceptTcpClient();

         StreamReader sr = new StreamReader(client.GetStream());

          StreamWriter sw = new StreamWriter(client.GetStream());

          try

          {

                //client's request

                 string request = sr.ReadLine();

                 Console.WriteLine(request);

                 string[] token = request.Split(' ');

                 string page = token[1];

                 Console.WriteLine("TYPE OF REQUEST = > [ "+token[0]+" ]");

                 Console.WriteLine("=====================================");

                 StreamReader reader = new StreamReader("../../Website"+page);

                 sw.WriteLine("HTTP/1.0 200 OK \n");

                 //Send That File to Client

                 string data = reader.ReadLine();

                 while (data != null)

                 {

                     sw.WriteLine(data);

                     sw.Flush();

 

                     //Next data

                     data=reader.ReadLine();

                 }

                 Console.WriteLine("==========================================");

            }

            catch(Exception e)

            {

                sw.WriteLine("HTTP/1.0 404 OK\n");

                sw.WriteLine("<h1><center>ERROR :'(</center></h1>");

                sw.Flush();

            }

            finally

            {

                client.Close();

            }                   

     }

Explanation

Assign TcpClient reference with the listener.AcceptTcpClient()

TcpClient client = listner.AcceptTcpClient();


Next, create an object of StreamWriter and StreamReader with respective arguments.
 

StreamReader sr = new StreamReader(client.GetStream());

StreamWriter sw = new StreamWriter(client.GetStream());

Here we use a try {}, catch {} and finally {} block to avoid exceptions, since we are working with streams and networks. So, it is mandatory.

Within the try { } block, read the request from the StreamReader and assign it to a request string. Print it to the Console.
 

string request = sr.ReadLine();

Console.WriteLine(request);

Since we have our request in a specific format. The first part of the request is the type of WebRequest (GET/POST) and the second part is the request. And it is separated by whitespace (that’s why, we used split(‘ ‘)).

So, our job is to split them and assign it to an array.
 

string[] token = request.Split(' ');

string page = token[1];

Console.WriteLine("TYPE OF REQUEST = > [ "+token[0]+" ]");

Here, I have taken a string array named "token" and assigned it with a split request since I want token[0] and token[1] for further use.

Since token[0] is the type of web request we got.

And token[1] is the actual request.

Note: My Solution Explorer is where I have a website window with two HTML files. I will use that HTML file in my output section.

HTML File

We will read the HTML code from the specified location as in the following:
 

StreamReader reader = new StreamReader("../../Website"+page);

  sw.WriteLine("HTTP/1.0 200 OK \n");

Here, the argument is quite unusual. Since we follow some web formats to send the actual page to the client.

“../../” is a web format to denote the Project Directory. Then I have written ‘Website+page’, that a Web Directory where I have put my HTML pages that will be sent to the client.

And the page is what we got from token[1] of the web request.

After completion, we send some positive response to the client, that we have found your request and successfully delivered it to you.

sw.WriteLine("HTTP/1.0 200 OK \n");


Then we send the entire desired data (HTML code) to the client using StreamWriter.

 

//Send That File to Client

string data = reader.ReadLine();

while (data != null)

{

      sw.WriteLine(data);

      sw.Flush();

      //Next data

      data=reader.ReadLine();

}


In the catch block, we handle the unusual errors that occur for whatever reason.
 

catch(Exception e)

{

        sw.WriteLine("HTTP/1.0 404 OK\n");

        sw.WriteLine("<h1><center>ERROR :'(</center></h1>");

        sw.Flush();

 }

 finally

{

     client.Close();

 }

There, we send some Web Response to the client, that we found some error and can’t send your desired data to you.
 

sw.WriteLine("HTTP/1.0 404 OK\n");

sw.WriteLine("<h1><center>ERROR :'(</center></h1>");


Step 4: Open the Project-Server Console and it will display something like this.

Server Console

Then open your Web Browser and type http://localhost:1500/Deafult.htm.

Since, localhost is pointing to the same computer.

And 1500 is the port the number that I assigned in the demo.

And "/Default.htm" is the desired page that I ‘m requesting from my server.

Default Page

You will get something like this:

Exception
In my Server Console, I have some LOG like this:

LOG

Where "Default.htm" is my requested page and GET is my type of request.

Now, we try our next request, that is "/Part.htm".

So:

Request
And then:

Home page
And in my Server Console:

Server Console

Moving to the last trial, let’s check some unknown .htm file.

So try with "/facebook.com" that doesn’t really exist.

Exception Catch Message
And it displays the exception’s catch message.

Exception

In the server’s console:

Servers Console Output

Conclusion

We have a simple demonstration of Client and Server. From here, you can move to other Web Services and Networking articles. For concerns regarding this article, if you encounter any issue then you can go with the enclosed project with it.