A network socket is a lot like an electrical socket. Various plugs around the network have a standard way of delivering their payload. Anything that understands the standard protocol can “plug in” to the socket and communicate. Internet Protocol is a low-level routing protocol that breaks data into small packets to the destination. Transmission Control Protocol (TCP) is a higher-level protocol that manages to robustly string together these packets, sorting and retransmitting them as necessary to reliably transmit your data.
Introduction:
A network socket is a lot like an electrical socket. Various plugs around the network have a standard way of delivering their payload. Anything that understands the standard protocol can “plug in” to the socket and communicate. Internet Protocol is a low-level routing protocol that breaks data into small packets to the destination. Transmission Control Protocol (TCP) is a higher-level protocol that manages to robustly string together these packets, sorting and retransmitting them as necessary to reliably transmit your data.
A server is anything that has some resource which can be shared. A client is simply any other entity that wants to gain access to a particular server. The interaction between client and server is just like the interaction between a lamp and an electrical socket. The power grid of the house is the server, and the lamp is a power client. The server is a permanently available resource, while the client is free to “unplug” after it has been served.
The notion of a socket allows a single computer to serve many different clients at once, as well as serving many different types of information. This feat is managed by the introduction of a port, which is a numbered socket on a particular machine. A server process is said to “listen” to a port until a client connects to it. A server is allowed to accept multiple clients connected to the same port number, although each session is unique.
In this article, our aim is to create socket-based programs. We will write two components:
• A server, which has stored a number of good quotations.
• A client, which will request for a quote and print it to the console.
The Server Program:
The server program instantiates an ArrayList and initializes it with quotation strings. It then uses the TcpListener class to create a socket connection on the local host. The Start() method of this class starts the process.
The following code snippet explains this:
TcpListener tcpl = new TcpListener(2010);
tcpl.Start();
next the TcpListener object listens for client connection, by calling its AcceptSocket() method, which keeps the process in a listening state, until it receives a client request. When the client connects, the AcceptSocket() method returns a socket object.
Socket sock = tcpl.AcceptSocket();
The Receive() method of the Socket object reads the input from the client. This method has three parameters. The first parameter is a byte array to store input; the second is the maximum number of bytes to read; and the third is the offset in the byte array to begin filling. This method returns the number of bytes read.
int count = sock.Receive(instream, instream.Length, 0);
The ASCIIEncoding class is used to convert the bytes array received from the client to a string. The GetString() method of ASCIIEncoding class performs this job. Its first parameter identifies the byte array to be converted, the second parameter is the byte array offset to begin at, and the third parameter is the number of bytes to read.
reqstring = ASCII.GetString(instream, 0, count);
After receiving the string from the client and printing it to the console, the server obtains a random string from the quotes ArrayList, converts it to a byte array. Lastly, it uses the Send() method of the Socket class to send the message back to the client.
rnd = new Random();
index = rnd.Next(msvr.quotes.Count);
outstream = ASCII.GetBytes((string)msvr.quotes[index]);
sock.Send(outstream, outstream.Length, 0);
The client can keep sending requests and must send the string “bye” to end communication. When the server receives this message it closes the socket connection.
The server program:
using System;
using System.Collections;
using System.Text;
using System.Net.Sockets;
namespace myserver
{
class myserver
{
ArrayList quotes = new ArrayList();
public myserver()
{
quotes.Add(" Imagination is more important than Knowledge");
quotes.Add(" Every really new idea looks crazy at first");
quotes.Add(" Reality is merely an illusion, albeit a very persistent one");
quotes.Add(" The way is not in the sky; the way is in the heart");
quotes.Add(" Let your heart guide you. It whispers, so listen closely");
}
static void Main(string[] args)
{
myserver msvr = new myserver();
ASCIIEncoding ASCII = new ASCIIEncoding();
Byte[] instream = new Byte[256];
Byte[] outstream = new Byte[256];
Random rnd;
string reqstring = " ";
int index;
TcpListener tcpl = new TcpListener(2010);
tcpl.Start();
Console.WriteLine("Server is Running...");
do
{
try
{
Socket sock = tcpl.AcceptSocket();
int count = sock.Receive(instream, instream.Length, 0);
reqstring = ASCII.GetString(instream, 0, count);
Console.WriteLine(reqstring);
rnd = new Random();
index = rnd.Next(msvr.quotes.Count);
outstream = ASCII.GetBytes((string)msvr.quotes[index]);
sock.Send(outstream, outstream.Length, 0);
}
catch (Exception e)
{
Console.WriteLine("Generic Exception Message: {0}", e.Message);
}
}
while (reqstring != "bye");
tcpl.Stop();
}
}
}
The Client Program:
The client program opens a connection to the server with the TcpClient class. The TcpClient object is instantiated with a constructor which accepts two arguments: the first one indicates the DNS host name of the server and the second argument is the port number.
TcpClient mycl = new TcpClient("localhost", 2010);
Next it obtains a stream from the server by using the GetStream() method of the TcpClient class.
Stream mystream = mycl.GetStream();
The string obtained is converted to a byte array, and the request is sent to the server with the Write() method of the Stream object.
outstream = ASCII.GetBytes("What is your next quote?");
Obtaining the quote from the server requires reading data from the input stream and converting the bytes to a string. Read() method of the Stream object is used to read from the server.
The Client Program:
class myclient
{
static void Main(string[] args)
{
ASCIIEncoding ASCII = new ASCIIEncoding();
Byte[] instream = new Byte[256];
Byte[] outstream = new Byte[256];
string advice;
string choice = "Q";
do{
try{
Console.WriteLine("\n Start a day:\n");
Console.WriteLine("1. Get quote");
Console.WriteLine("Q. Quit");
Console.WriteLine("\n Please Choose: ");
choice = Console.ReadLine();
Console.WriteLine();
TcpClient mycl = new TcpClient("localhost", 2010);
Stream mystream = mycl.GetStream();
outstream = ASCII.GetBytes("What is your next quote?");
if(choice == "1")
{
//send request to server
mystream.Write(outstream, 0, outstream.Length);
//garbage clearence
for(int i=0; i<instream.Length; i++)
{
instream[i] = 0;
}
//retrieve response from server
mystream.Read(instream,0,instream.Length);
advice = ASCII.GetString(instream, 0, instream.Length);
Console.WriteLine("Server Response: {0}", advice);
}
else
{
//close session
outstream = ASCII.GetBytes("bye");
mystream.Write(outstream, 0, outstream.Length);
}
}
catch( InvalidOperationException ioe)
{
Console.WriteLine("Invalid Operation Message: {0}", ioe.Message);
}
catch ( Exception e)
{
Console.WriteLine("Generic Exception Message: {0}", e.Message);
}
}
while (choice == "1");
}
}
To check these programs, first compile and run the server program and then open another window and compile and run the client program. The client program console looks like:
Conclusion:
The C# language has access to an entire suite of networking libraries. Some of its capabilities range from low-level socket connections to wrapped HTTP classes. Though these days distributed, n-tier concepts are gaining focus, some of the legacy system and Internet utilities still uses client-server computing.