Socket Programming in C#
 
Published: 24 Jan 2008
Unedited - Community Contributed
Abstract
In this article, Joydip demonstrates the working of socket programming in C#. He starts with a brief introduction of sockets and ports and examines the differences between synchronous and asynchronous Communication. You will then learn how to work with System.Net and System.Net.Sockets namespaces along with the implementation of a simple client-server application. The article is well supported by relevant source codes and its corresponding output in screenshots.
by Joydip Kanjilal
Feedback
Average Rating: 
Views (Total / Last 10 Days): 48184/ 54

Introduction

A Computer Network implies two or more computers linked together through some software or hardware for the purpose of exchanging data and information. Microsoft .NET provides excellent support for writing programs that can make use of sockets for communication between two or more programs over a network. We will learn more about sockets and ports as we progress through the sections that follow. This article discusses how we can work with Sockets in .NET for writing programs that can communicate over a network. Note that the code examples provided in this article are in C#.

Understanding Sockets and Ports

A socket is the end point of a two way communication between two systems running over a network. When two or more processes communicate over a network, they communicate using Sockets. A port implies an unsigned integer that uniquely identifies a process running over a network. The following are some of the well known port numbers distinguished by the type of services that they provide:

·         HTTP                 80

·         Telnet                23

·         SMTP                 25

·         SNPP                 444

·         DNS                  53

·         FTP (Data)          20

·         FTP (Control)      21  

Synchronous and Asynchronous Communications

In Microsoft .NET, you have support for both synchronous and asynchronous communication using sockets. Incidentally, these are also known as blocking and non-blocking modes of operation. There are subtle differences between the two. When working in the synchronous mode, a method call blocks itself unless the operation is complete in all respects. In the other mode of operation, i.e., the asynchronous mode, a method returns even before its turnaround time has elapsed. Fine, but what is turnaround time? Well, turnaround time refers to the total time taken by a thread to be complete in all respects.

In such a mode of communication, the server application listens to a specific port to receive data from the clients. In doing so, the server application is blocked (for other client requests) unless it receives data from the client application. On the other hand, while operating in the asynchronous mode, the server can process multiple client requests at the same point of time. Note that the asynchronous operations using sockets are typically used for long running tasks. Typical examples of such tasks are opening large files, reading or querying a database with large volumes of data, connecting to a remote computer, accessing resources remotely for long running operations, etc. Further, note that the asynchronous operations actually operate on a separate thread. Typically, applications have two types of threads, application thread and worker thread. An application thread is the main thread of the application; the worker thread is the thread that works in the background to perform asynchronous operations.

Note that the Socket class in the System.Net.Sockets namespace contains both synchronous and asynchronous methods. As an example, while the Connect() and Receive() methods are meant for synchronous operation, the BeginConnect() and EndConnect() methods as well as the BeginReceive() and EndReceive() methods are their asynchronous counterparts.

Working with the System.Net and System.Net.Sockets namespaces

The Socket class in the System.Net.Sockets namespace is used for working with Sockets in C#. Note that there is a local and also a remote end point associated with each socket. We will learn more on this class later in the article.

The System.Net namespace class contains an important class called Dns that can be used to access DNS (Domain Naming Service). Well, what is a DNS, anyway? Domain Naming Service or DNS is a naming service that is used to name the nodes over a network for simplicity reasons. The domain name is actually a textual name that identifies a host in a network. The DNS servers have the DNS names stored along with their corresponding IP addresses. The Wikipedia states, "The Domain Name system (DNS) associates various sorts of information with so-called domain names; most importantly, it serves as the "phone book" for the Internet by translating human-readable computer hostnames, e.g. www.example.com, into the IP addresses, e.g. 208.77.188.166, that networking equipment needs to deliver information. It also stores other information such as the list of mail exchange servers that accept email for a given domain. In providing a worldwide keyword-based redirection service, the Domain Name System is an essential component of contemporary Internet use."

Now, in order to retrieve the host name of your local system, use the following:

Listing 1

Console.WriteLine("The host name of the local computer is: " + Dns.GetHostName());

The host name of the local computer is displayed as shown in the figure below.

Figure 1

In the above code snippet, GetHostName() is a static method of the Dns class. Here is a simple program that illustrates how you can display the IP address of the www.hotmail.com web site using this class.

Listing 2: Displaying the IP address of Hotmail using Sockets

using System;
using System.Text;
using System.Net;
using System.Net.Sockets;
namespace TestSocket
{
  class Program
  {
    static void Main(string[]args)
    {
      try
      {
        IPHostEntry IPHost = Dns.GetHostEntry("www.hotmail.com");
        IPAddress[]ipAddress = IPHost.AddressList;
        StringBuilder strIpAddress = new StringBuilder();
 
        for (int i = 0; i < ipAddress.Length; i++)
        {
          strIpAddress.Append(ipAddress[i].ToString());
        }
 
        Console.WriteLine("The IP Address is: " + strIpAddress.ToString());
      }
      catch (SocketException ex)
      {
        Console.WriteLine("Error Occured! " + ex);
      }
 
      Console.Read();
    }
  }
}

When you execute the above program, the IP address of www.hotmail.com. In this case it displayed as 211.206.123.219. However, if you are not connected to the network, the method fails and a SocketException is thrown. The exception is caught in the catch block shown in the above program. The figures below illustrate the output in each case.

Figure 2

Figure 3: The message for the SocketException thrown when not connected

Implementing a Simple Server – Client Application using Sockets

In this section we will discuss how to implement a simple client-server application using Sockets in C#. There will be two distinct applications, i.e., a Server application and a Client application. The Server application will connect to a port and be in the listen mode waiting for a Client to connect. Once the Client is connected, it will send a test message to the Server application using a StreamWriter. This text message will then be displayed in the Server application's console.

Here is the source code of the Server application.

Listing 3: The SocketServer class

using System;
using System.Text;
using System.Net;
using System.Net.Sockets;
 
class SocketServer
{
  public static void Main()
  {
    StreamWriter streamWriter;
    StreamReader streamReader;
    NetworkStream networkStream;
    TcpListener tcpListener = new TcpListener(5555);
    tcpListener.Start();
    Console.WriteLine("The Server has started on port 5555");
    Socket serverSocket = tcpListener.AcceptSocket();
    try
    {
      if (serverSocket.Connected)
      {
        while (true)
        {
          Console.WriteLine("Client connected");
          networkStream = new NetworkStream(serverSocket);
          streamWriter = new StreamWriter(networkStream);
          streamReader = new StreamReader(networkStream);
          Console.WriteLine(streamReader.ReadLine());
 
        }
      }
      if (serverSocket.Connected)
        serverSocket.Close();
      Console.Read();
    }
    catch (SocketException ex)
    {
      Console.WriteLine(ex);
    }
  }
}

Refer to the code snippet given above. The Server application starts the port 5555; displays a relevant message and waits for the incoming requests from the Client to connect to it. Now, when you run this application, the message "The Server has started on port 5555" will be displayed on the Server application's console. As soon as a Client gets connected to the same port, the message "Client connected" is displayed on the console. Here is the output when you execute this application.

Figure 4: The SocketServer console when started

Next, we will take a look at the source code of the Client application that will connect to the Server application using the same port, i.e., 5555. Here is the code.

Listing 4: The SocketClient class

using System;
using System.Text;
using System.Net;
using System.Net.Sockets;
 
class SocketClient
{
  static void Main(string[]args)
  {
    TcpClient tcpClient;
    NetworkStream networkStream;
    StreamReader streamReader;
    StreamWriter streamWriter;
    try
    {
      tcpClient = new TcpClient("localhost", 5555);
      networkStream = tcpClient.GetStream();
      streamReader = new StreamReader(networkStream);
      streamWriter = new StreamWriter(networkStream);
      streamWriter.WriteLine("Message from the Client...");
      streamWriter.Flush();
    }
    catch (SocketException ex)
    {
      Console.WriteLine(ex);
    }
    Console.Read();
  }
}

When you execute the Client application, here is how the output will look like at the Server application’s console.

Figure 5: The SocketServer console when the client is connected

Note that the message "Client connected" and the text sent by the client, "Message from the Client…", is displayed at the Server application’s console.

Conclusion

A Port is an unsigned integer that uniquely identifies a process running over a network for the purpose of providing a service. A socket is the end point of a two way communication between two processes running over a network. Microsoft .NET provides excellent support for writing programs that leverage the power of Sockets to implement programs that can run over a network to communicate and share data and information. In this article we have had a look at how we can work with Sockets using Microsoft .NET and how we can implement a simple client-server program that can communicate over a network. Reader's comments and suggestions are welcome. Happy reading!



User Comments

No comments posted yet.






Community Advice: ASP | SQL | XML | Regular Expressions | Windows


©Copyright 1998-2024 ASPAlliance.com  |  Page Processed at 2024-04-26 9:21:57 AM  AspAlliance Recent Articles RSS Feed
About ASPAlliance | Newsgroups | Advertise | Authors | Email Lists | Feedback | Link To Us | Privacy | Search