Friday, 9 December 2016

C#: Socket Programming

By using socket programming, you can establish a communication between two computers. By using C# Socket programming, you can establish communication between, two C# applications running on different machines.

In this post, I am going to explain two applications client, server. Server socket listens on particular port, client socket sends some data to the server. Server socket receives the data from client socket and prints to console.

You need to import following packages to work with sockets.

using System.Net;
using System.Net.Sockets;

Developing Server Socket
Socket class is used to define both server and client sockets. IN case of server socket, we bind to particular address, where as in client socket we connect to particular address.

Socket class provides following constructors.

Constructor
Description
Socket(AddressFamily, SocketType, ProtocolType)
Initializes a new instance of the Socket class using the specified address family, socket type and protocol.
Socket(SocketInformation)   
Initializes a new instance of the Socket class using the specified value returned from DuplicateAndClose.
Socket(SocketType, ProtocolType)     
Initializes a new instance of the Socket class using the specified socket type and protocol.
        
What is AddressFamily?
It specifies the addressing scheme of the Socket.
 For example,
 ‘AddressFamily.InterNetwork’ specifies Address for IP version 4.         
 ‘AddressFamily.InterNetworkV6’ specifies Address for IP version 6.

What is SocketType?
SocketType specifies the type of the socket, it can be Dgram, Raw, Rdm, Seqpacket, Stream, Unknown.

Go to following link for more information.

What is ProtocolType?
Specified the protocol used by socket. For example, it can be Tcp, Udp. Following link documents all the supported protocols.


Following step-by-step procedure explains how to create Server Socket?

Step 1: Define Socket object.

Socket serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

Step 2: Define IOEndPoint.

IPEndPoint serverEndPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), port);

Step 3: Bind serverSocket to serverEndPoint.
serverSocket.Bind(serverEndPoint);
serverSocket.Listen(100);

Step 4: Now you can accept the connections by calling Accept method. You can receive the data from client to byte array.

Socket accepted = serverSocket.Accept();
int bytesRead = accepted.Receive(buffer);

Following step-by-step procedure explains how to create client socket?

Step 1: Define client socket.
Socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

Step 2: Connect to server end point.
IPEndPoint serverEndPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), port);
clientSocket.Connect(serverEndPoint);

Step 3: Send data to server socket.
clientSocket.Send(bytes);

Step 4: Close the client socket, after you are done with the work.
clientSocket.Close();

Following are the complete working applications.
Server.cs
using System;
using System.Text;
using System.Net;
using System.Net.Sockets;

namespace Server
{
    public class ServerSocket
    {
        private int port;
        private Socket serverSocket;

        public ServerSocket(int port)
        {
            this.port = port;
            serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

            IPEndPoint serverEndPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), port);

            /* Associates a Socket with a local endpoint. */
            serverSocket.Bind(serverEndPoint);

            /*Places a Socket in a listening state.
             * The maximum length of the pending connections queue is 100 
             */
            serverSocket.Listen(100);
        }

        public void start()
        {
            Console.WriteLine("Starting the Server");

            /* Accept Connection Requests */
            Socket accepted = serverSocket.Accept();

            /* Get the size of the send buffer of the Socket. */
            int bufferSize = accepted.SendBufferSize;
            byte[] buffer = new byte[bufferSize];

            /* Receives data from a bound Socket into a receive buffer. It return the number of bytes received. */
            int bytesRead = accepted.Receive(buffer);

            byte[] formatted = new byte[bytesRead];

            for (int i = 0; i < bytesRead; i++)
            {
                formatted[i] = buffer[i];
            }

            String receivedData = Encoding.Unicode.GetString(formatted);
            Console.WriteLine("Received Data " + receivedData);

            Console.WriteLine("Press some key to close");
            Console.Read();
        }
    }
    class Server
    {
        static void Main(string[] args)
        {
            ServerSocket server = new ServerSocket(1234);
            server.start();
        }
    }
}

Client.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.Net.Sockets;

namespace client
{
    public class ClientSocket{
        private Socket clientSocket;
        private int port;

        public ClientSocket(int port)
        {
            this.port = port;
            clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        }

        public void start()
        {
            Console.WriteLine("Starting client socket");
            try
            {
                IPEndPoint serverEndPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), port);
                clientSocket.Connect(serverEndPoint);

                Console.WriteLine("Enter some data to send to server");

                String data = Console.ReadLine();

                byte[] bytes = Encoding.Unicode.GetBytes(data);

                clientSocket.Send(bytes);

                Console.WriteLine("Closing connection");

                clientSocket.Close();
            }
            catch (Exception e)
            {
                Console.WriteLine("Error while connectiong to server {}", e.Message );
            }
        }
    }

    class Client
    {
        static void Main(string[] args)
        {
            ClientSocket clientSocket = new ClientSocket(1234);
            clientSocket.start();

        }
    }
}

Following is my project structure.
Right click on server project. Go to Debug -> Start New Instance.

It opens command prompt and wait for some connection.

Now right click on client project, go to Debug -> Start New Instance.

It opens command prompt, type some data and press enter. Open the server command prompt, you can able to see the data that you entered in client end point.


Previous                                                 Next                                                 Home

No comments:

Post a Comment