[RELEASE]Asynchronous Socket in C# Designed Similar to Old Winsock

09/19/2012 18:01 xmen01235#1
I would like to share also my socket wrapper but this time it is in C# and this is almost similar to my VB version except that I add a lot of stuff on it to improve the performance and I put a RaiseEventSafe() function to manage the event in a safe manner.(The safe raisevent function is not done by me but I just borrow it from this example [Only registered and activated users can see links. Click Here To Register...])

Code:
using System;
using System.Net.Sockets;
using System.Net;
using System.ComponentModel;

namespace xmen
{
    internal class mysocket
    {
        #region Private
        private Socket _listener;
        private Socket client;


        private int _localport;
        private int _remoteport;
        private string _remoteIP;


        private byte[] data;
        private const int ByteSize = 8192;
        private int _Status;

        private static object _lock = new object();
        #endregion

        #region Public Property
        public int Status
        {
            get { return _Status; }
        }
        public int LocalPort
        {
            get { return this._localport; }
            set { this._localport = value; }
        }
        public int RemotePort
        {
            get { return this._remoteport; }
            set { this._remoteport = value; }
        }
        public string RemoteIP
        {
            get { return this._remoteIP; }
            set { this._remoteIP = value; }
        }

        #endregion

        #region Public Events
        private void RaiseEventSafe(System.Delegate ev, ref object[] args)
        {
            Boolean bFired;
            if (ev != null)
            {
                foreach (System.Delegate singleCast in ev.GetInvocationList())
                {
                    bFired = false;
                    try
                    {
                        ISynchronizeInvoke syncInvoke = (ISynchronizeInvoke)singleCast.Target;
                        if (syncInvoke != null && syncInvoke.InvokeRequired)
                        {
                            bFired = true;
                            syncInvoke.BeginInvoke(singleCast, args);
                        }
                        else
                        {
                            bFired = true;
                            singleCast.DynamicInvoke(args);
                        }
                    }
                    catch
                    {
                        if (!bFired)
                        {
                            singleCast.DynamicInvoke(args);
                        }
                    }
                }
            }
        }

        private event EventHandler SendCompleteEvent;
        public event EventHandler OnSendComplete
        {
            add
            {
                lock (_lock)
                {
                    SendCompleteEvent += value;
                }
            }
            remove { lock (_lock) SendCompleteEvent -= value; }
        }
        private event EventHandler DataArrivalEvent;
        public event EventHandler OnDataArrival
        {
            add
            {
                lock (_lock)
                {
                    DataArrivalEvent += value;
                }
            }
            remove { lock (_lock) DataArrivalEvent -= value; }

        }
        private event EventHandler ConnectEvent;
        public event EventHandler OnConnect
        {
            add
            {
                lock (_lock)
                {
                    OnConnect += value;
                }
            }
            remove { lock (_lock) OnConnect -= value; }
        }
        private event EventHandler DisconnectEvent;
        public event EventHandler OnDisconnect
        {

            add
            {
                lock (_lock)
                {
                    DisconnectEvent += value;
                }
            }
            remove { lock (_lock) DisconnectEvent -= value; }

        }
        private event EventHandler ConnectionRequestEvent;
        public event EventHandler OnConnectionRequest
        {

            add
            {
                lock (_lock)
                {
                    ConnectionRequestEvent += value;
                }
            }
            remove { lock (_lock) ConnectionRequestEvent -= value; }
        }
        #endregion

        #region Constructor
        public mysocket()
        {
            data = new byte[ByteSize];
            _Status = 0;
        }
        #endregion

        #region Public Methods
        public void Listen(string IP)
        {
            try
            {

                _listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                IPEndPoint IEP = new IPEndPoint(IPAddress.Parse(IP), this._localport);
                _listener.ExclusiveAddressUse = true;
                _listener.Bind(IEP);
                _listener.Listen(100);

            }
            catch (Exception ex)
            {
                throw new System.ArgumentException(ex.ToString());
            }
            _listener.BeginAccept(new AsyncCallback(WaitConnections), _listener);

        }
        public void StopListen()
        {
            try
            {
                this._listener.Close();
            }
            catch (Exception ex)
            {
                throw new System.ArgumentException(ex.ToString());
            }
        }
        public void Accept(Socket newclient)
        {
            try
            {
                this.client = newclient;
                this.client.BeginReceive(data, 0, ByteSize, SocketFlags.None, new AsyncCallback(ReceiveData), this.client);

                _Status = 1;
                // Connected
            }
            catch (Exception ex)
            {
                throw new System.ArgumentException(ex.ToString());
            }
        }
        public void GetData(ref byte[] buffer, int bytestotal)
        {
            buffer = new byte[bytestotal];
            System.Buffer.BlockCopy(this.data, 0, buffer, 0, bytestotal);
        }
        public void Connect()
        {


                AsyncCallback connectedCallback = new AsyncCallback(Connected);
                this.client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                IPEndPoint iep = new IPEndPoint(IPAddress.Parse(this._remoteIP), this._remoteport);
                IAsyncResult asyncRes = client.BeginConnect(iep, connectedCallback, client);


        }
        public void SendData(byte[] buffer)
        {
            try
            {
                if (client.Connected)
                {
                    this.client.BeginSend(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(SendComplete), this.client);
                    //sendThread = New Thread(AddressOf SendComplete)
                    //sendThread.IsBackground = True
                    //sendThread.Start()
                }
                else
                {
                }
            }
            catch (Exception ex)
            {
                throw new System.ArgumentException(ex.ToString());
            }
        }
        public void Close()
        {
            lock (this)
            {
                if (this.client.Connected)
                {
                    try
                    {
                        this.client.Shutdown(SocketShutdown.Both);
                        this.client.Close();

                        _Status = 0;

                        object[] objevent = { "Disconnected", EventArgs.Empty };
                        RaiseEventSafe(DisconnectEvent, ref objevent);
                        
                        // Disconnected
                    }
                    catch (Exception ex)
                    {
                        throw new System.ArgumentException(ex.ToString());
                    }
                }
            }
        }
        #endregion

        #region Private Method




        private void ReceiveData(IAsyncResult iar)
        {
            try
            {
                try
                {
                    this.client = (Socket)iar.AsyncState;
                    SocketError SE = new SocketError();
                    if (this.client.Connected)
                    {
                        int datalen = this.client.EndReceive(iar, out SE);
                        if (SE == SocketError.Success & datalen != 0)
                        {
                            byte[] buffer;
                            buffer = new byte[datalen];
                            System.Buffer.BlockCopy(this.data, 0, buffer, 0, datalen);
                            object[] objevent = { buffer, EventArgs.Empty };
                            this.RaiseEventSafe(DataArrivalEvent, ref objevent);

                            this.client.BeginReceive(data, 0, ByteSize, SocketFlags.None, new AsyncCallback(ReceiveData), this.client);
                        }
                        else
                        {
                            _Status = 0;
                            // Disconnected
                            object[] objevent = { "Disconnected", EventArgs.Empty };
                            RaiseEventSafe(DisconnectEvent, ref objevent);
                        }
                    }
                    else
                    {
                        _Status = 0;
                        // Disconnected
                        object[] objevent = { "Disconnected", EventArgs.Empty };
                        RaiseEventSafe(DisconnectEvent, ref objevent);
                    }
                }
                catch (Exception ex)
                {
                    throw new System.ArgumentException(ex.ToString());
                }
            }
            catch (Exception ex)
            {
                throw new System.ArgumentException(ex.ToString());
            }
        }
        private void WaitConnections(IAsyncResult iar)
        {
            lock (this)
            {
                try
                {
                    Socket tmpsoc = (Socket)iar.AsyncState;
                    Socket mclient = tmpsoc.EndAccept(iar);

                    object[] objevent = { mclient, EventArgs.Empty };
                    RaiseEventSafe(ConnectionRequestEvent, ref objevent);
                }
                catch
                {

                    try
                    {
                        this._listener.BeginAccept(new AsyncCallback(WaitConnections), _listener);
                        return;
                    }
                    catch (Exception ex1)
                    {
                        throw new System.ArgumentException(ex1.ToString());

                    }
                }
                try
                {
                    this._listener.BeginAccept(new AsyncCallback(WaitConnections), _listener);
                }
                catch (Exception ex)
                {
                    throw new System.ArgumentException(ex.ToString());

                }
            }
        }
        private void SendComplete(IAsyncResult iar)
        {
            int sent = 0;
            try
            {
                Socket remote = (Socket)iar.AsyncState;
                sent = remote.EndSend(iar);

                object[] objevent = { sent, EventArgs.Empty };
                this.RaiseEventSafe(SendCompleteEvent, ref objevent);
                
            }
            catch (Exception ex)
            {
                throw new System.ArgumentException(ex.ToString());
            }
        }
        private void Connected(IAsyncResult iar)
        {
            try
            {
                this.client = (Socket)iar.AsyncState;
                this.client.EndConnect(iar);
                client.BeginReceive(data, 0, ByteSize, SocketFlags.None, new AsyncCallback(ReceiveData), client);

                _Status = 1;
                // Connected
                object[] objevent = { "Connected", EventArgs.Empty };
                RaiseEventSafe(ConnectEvent, ref objevent);

                /*readThread = new Thread(ReceiveData);
                readThread.IsBackground = true;
                readThread.Start();*/

            }
            catch (Exception ex)
            {
                this.client.Close();
                throw new System.ArgumentException(ex.ToString());
            }
        }

        private bool Resolve(string IP, int port)
        {

            Socket s = new Socket(AddressFamily.InterNetwork,
                SocketType.Stream,
                ProtocolType.Tcp);
            try
            {
                s.Connect(IPAddress.Parse(IP), port);
                s.Disconnect(true);
                return true;
            }
            catch
            {
                return false;
            }


        }
        #endregion

    }
}
Implementation:
Code:
        private mysocket listener=new mysocket();
        private mysocket CPSoc = new mysocket();

        public void StartServer()
        {
            this.listener.LocalPort = 9960;               
            this.listener.Listen("192.168.10.23");
            this.listener.OnConnectionRequest+=new EventHandler(listener_ConnectionRequest);
        }

        private void listener_ConnectionRequest(object sender, EventArgs e)
        {
             this.CPSoc.Accept((Socket)sender);
            this.CPSoc.OnDataArrival += new EventHandler(CPSoc_DataArrival);
            this.CPSoc.OnDisconnect+=new EventHandler(CPSoc_ErrorReceived);

        }

        private void CPSoc_DataArrival(object sender, EventArgs e)
        {
            byte[] bytedata = (byte[])sender;
            // Add your data arrival code here
        }

        private void CPSoc_ErrorReceived(object sender, EventArgs e)
        {
              // Add your connection error code here
        }

       private SendToClient(byte[] msg)
       {
           CPSoc.SendData(msg);
       }