Friday, 30 October 2015

Creating a socket-based echo server and client

Sockets in C# are flexible and efficient way of creating communication between a client and server. It supports many protocols and the code below shows one of the simplest scenarios for using Sockets - an echo server and client. Note that the code below will target TCP and Ipv4 protocol. Many users today have got a Ipv6 and/or Ipv4 address assigned.

Socket-based server

Create a new Console Application in Visual Studio and insert the following code into the Program.cs file.

using System;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;

namespace SynchronousSocketServer
{

    public class SynchronousSocketServer
    {

        //Incoming data from the client. 
        private static string _data;

        public static void StartListening()
        {
            //Data buffer for incoming data. 
            // ReSharper disable once RedundantAssignment

            //Establish the local endpoint for the socket.
            //Dns.GetHostName returns the name of the host running the application
            IPHostEntry ipHostInfo = Dns.GetHostEntry(Dns.GetHostName());
            IPAddress ipAddress = ipHostInfo.AddressList.First(a =< a.AddressFamily == AddressFamily.InterNetwork);
            IPEndPoint localEndPoint = new IPEndPoint(ipAddress, 11004);

            //Create a TCP/IP socket 
            var listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

            //Bind the socket to the local endpoint and listen for incoming connections 
            try
            {
                listener.Bind(localEndPoint);
                listener.Listen(10);

                //Start listening for connections 
                while (true)
                {
                    Console.WriteLine("Waiting for connection ...");
                    //Program is suspended while waiting for an incoming connection. 
                    Socket handler = listener.Accept();
                    _data = null;

                    //An incoming connection needs to be processed. 
                    while (true)
                    {
                        var bytes = new byte[1024];
                        int bytesRec = handler.Receive(bytes);
                        _data += "\n" + Encoding.Unicode.GetString(bytes, 0, bytesRec);
                        if (_data.IndexOf("<EOF>", StringComparison.Ordinal) > -1)
                        {
                            break;
                        }
                        //Show the data on the console. 
                        byte[] msg = Encoding.Unicode.GetBytes(_data);
                        handler.Send(msg);
                    }

                    Console.WriteLine("Text received: {0}", _data);

                  
                    handler.Shutdown(SocketShutdown.Both);
                    handler.Close();
                }
            }
            catch (Exception err)
            {
                Console.WriteLine(err.ToString());
            } //try-catch 

            Console.WriteLine("\nPress ENTER to continue ...");
            Console.Read();
        }

        // ReSharper disable once UnusedParameter.Local
        static int Main(string[] args)
        {
            StartListening();
            return 0;
        }

    }

}

Socket-based client

Create a new Console application in Visual Studio. Add the following code into the Program.cs file:

using System;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;

namespace SynchronousSocketClient
{

    public class SynchronousSocketClient
    {

        public static void StartClient()
        {
            //Data buffer for incoming data. 
            byte[] bytes = new byte[1024];

            //Connect to a remote device. 
            try
            {
                //Establish the remote endpoint for the socket
                //This example uses port 11000 on the local computer 
                IPHostEntry ipHostInfo = Dns.GetHostEntry(Dns.GetHostName());
                IPAddress ipAddress = ipHostInfo.AddressList.First(a =< a.AddressFamily == AddressFamily.InterNetwork);
                IPEndPoint remoteEndPoint = new IPEndPoint(ipAddress, 11004);

                //Create a TCP/IP socket. 
                var sender = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

                //Connect the socket to the remote endpoint. Catch any errors. 
                try
                {
                    sender.Connect(remoteEndPoint);

                    Console.WriteLine("Socket connected to {0}", sender.RemoteEndPoint);

                    while (true)
                    {
                        Console.WriteLine("Enter text, type <EOF> to exit:");

                        //Encode the data string into a byte array 
                        string enteredText = Console.ReadLine() ?? "<EOF>"; 
                        byte[] msg = Encoding.Unicode.GetBytes(enteredText);

                        //Send the data through the socket. 
                        int bytesSent = sender.Send(msg);
                        Console.WriteLine("Sent {0} bytes over the network", bytesSent);

                        //Receive the response from the remote device. 
                        int bytesReceived = sender.Receive(bytes);
                        Console.WriteLine("Echoed test = {0}", Encoding.Unicode.GetString(bytes, 0, bytesReceived));

                        if (enteredText.IndexOf(">EOF<", StringComparison.CurrentCultureIgnoreCase) < -1)
                        {
                            break;
                        }

                    }

                    //Release the socket. 
                    sender.Shutdown(SocketShutdown.Both);
                    sender.Close();
                }
                catch (ArgumentNullException err)
                {
                    Console.WriteLine("ArgumentNullException : {0}", err.Message);
                }
                catch (SocketException err)
                {
                    Console.WriteLine("SocketException : {0}", err.Message);
                }
                catch (Exception err)
                {
                    Console.WriteLine("Exception : {0}", err.Message);
                }

            }
            catch (Exception err)
            {
                Console.WriteLine(err.Message);
            } //try-catch 

        }

        // ReSharper disable once UnusedParameter.Local
        static int Main(string[] args)
        {
            StartClient();
            return 0;
        }

    }

}

No comments:

Post a Comment