All pastes #18683 Raw Edit

Miscellany

public text v1 · immutable
#18683 ·published 2005-07-28 06:54 UTC
rendered paste body
using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Threading;

namespace SocketSystem
{
    class CSocketClient
    {
        #region delegates
        /// <summary> DelType: Called when a message is received </summary>
        public delegate void MESSAGE_HANDLER(CSocketClient pSocket, Int32 iNumberOfBytes);
        /// <summary> DelType: Called when a connection is closed </summary>
        public delegate void CLOSE_HANDLER(CSocketClient pSocket);
        /// <summary> DelType: Called when a socket error occurs </summary>
        public delegate void ERROR_HANDLER(CSocketClient pSocket, Exception pException);
        #endregion

        #region private variables
        /// <summary> RefType: A network stream object </summary>
        private NetworkStream m_pNetworkStream;
        private NetworkStream GetNetworkStream
        {
            get { return m_pNetworkStream; }
            set { m_pNetworkStream = value; }
        }
        /// <summary> RefType: A TcpClient object for socket connection </summary>
        private TcpClient m_pTcpClient;
        private TcpClient GetTcpClient
        {
            get { return m_pTcpClient; }
            set { m_pTcpClient = value; }
        }
        /// <summary> RetType: A callback object for processing recieved socket data </summary>
        private AsyncCallback m_pCallbackReadMethod;
        private AsyncCallback GetCallbackReadMethod
        {
            get { return m_pCallbackReadMethod; }
            set { m_pCallbackReadMethod = value; }
        }
        /// <summary> RetType: A callback object for processing send socket data </summary>
        private AsyncCallback m_pCallbackWriteMethod;
        private AsyncCallback GetCallbackWriteMethod
        {
            get { return m_pCallbackWriteMethod; }
            set { m_pCallbackWriteMethod = value; }
        }
        /// <summary> DelType: A reference to a user supplied function to be called when a socket message arrives </summary>
        private MESSAGE_HANDLER m_pfnMessageHandler;
        private MESSAGE_HANDLER GetMessageHandler
        {
            get { return m_pfnMessageHandler; }
            set { m_pfnMessageHandler = value; }
        }
        /// <summary> DelType: A reference to a user supplied function to be called when a socket connection is closed </summary>
        private CLOSE_HANDLER m_pfnCloseHandler;
        private CLOSE_HANDLER GetCloseHandler
        {
            get { return m_pfnCloseHandler; }
            set { m_pfnCloseHandler = value; }
        }
        /// <summary> DelType: A reference to a user supplied function to be called when a socket error occurs </summary>
        private ERROR_HANDLER m_pfnErrorHandler;
        private ERROR_HANDLER GetErrorHandler
        {
            get { return m_pfnErrorHandler; }
            set { m_pfnErrorHandler = value; }
        }
        /// <summary> SimType: Flag to indicate if the class has been disposed </summary>
        private Boolean m_bDisposeFlag;
        private Boolean IsDisposed
        {
            get { return m_bDisposeFlag; }
            set { m_bDisposeFlag = value; }
        } 
        #endregion


        #region public variables
        /// <summary> RefType: The IpAddress the client is connect to </summary>
        private String m_strIpAddress;
        public String GetIpAddress
        {
            get { return m_strIpAddress; }
            set { m_strIpAddress = value; }
        }
        /// <summary> SimType: The Port to either connect to or listen on </summary>
        private Int16 m_iPort;
        public Int16 GetPort
        {
            get { return m_iPort; }
            set { m_iPort = value; }
        }
        /// <summary> RefType: A reference to a user defined object </summary>
        private Object m_pUserArg;
        public Object GetUserArg
        {
            get { return m_pUserArg; }
            set { m_pUserArg = value; }
        }

        /// <summary> SimType: A raw buffer to capture data comming off the socket </summary>
        private Byte[] m_bytRawBuffer;
        public Byte[] GetRawBuffer
        {
            get { return m_bytRawBuffer; }
            set { m_bytRawBuffer = value; }
        }
        /// <summary> SimType: Size of the raw buffer for received socket data </summary>
        private Int32 m_iSizeOfRawBuffer;
        public Int32 GetSizeOfRawBuffer
        {
            get { return m_iSizeOfRawBuffer; }
            set { m_iSizeOfRawBuffer = value; }
        } 
        #endregion


        #region constructor + finialise + dispose
        /// <summary> Constructor for client support </summary>
        /// <param name="iSizeOfRawBuffer"> SimType: The size of the raw buffer </param>
        /// <param name="pUserArg"> RefType: A Reference to the Users arguments </param>
        /// <param name="pfnMessageHandler"> DelType: Reference to the user defined message handler method </param>
        /// <param name="pfnCloseHandler"> DelType: Reference to the user defined close handler method </param>
        /// <param name="pfnErrorHandler"> DelType: Reference to the user defined error handler method </param>
        public CSocketClient(Int32 iSizeOfRawBuffer, Object pUserArg, MESSAGE_HANDLER pfnMessageHandler,
            CLOSE_HANDLER pfnCloseHandler, ERROR_HANDLER pfnErrorHandler)
        {
            // Create the raw buffer
            GetSizeOfRawBuffer = iSizeOfRawBuffer;
            GetRawBuffer = new Byte[GetSizeOfRawBuffer];

            // Save the user argument
            GetUserArg = pUserArg;

            // Set the handler methods
            GetMessageHandler = pfnMessageHandler;
            GetCloseHandler = pfnCloseHandler;
            GetErrorHandler = pfnErrorHandler;

            // Set the async socket method handlers
            GetCallbackReadMethod = new AsyncCallback(ReceiveComplete);
            GetCallbackWriteMethod = new AsyncCallback(SendComplete);

            // Init the dispose flag
            IsDisposed = false;
        }
        /// <summary> Finialize </summary>
        ~CSocketClient()
        {
            if (!IsDisposed)
                Dispose();
        }
        /// <summary> Dispose </summary>
        public void Dispose()
        {
            try
            {
                // Flag that dispose has been called
                IsDisposed = true;
                // Disconnect the client from the server
                Disconnect();
            }
            catch
            {
            }
        }
        #endregion


        #region private methods
        /// <summary> Called when a message arrives </summary>
        /// <param name="ar"> RefType: An async result interface </param>
        private void ReceiveComplete(IAsyncResult ar)
        {
            try
            {
                // Is the Network Stream object valid
                if (GetNetworkStream.CanRead)
                {
                    // Read the current bytes from the stream buffer
                    Int32 iBytesRecieved = GetNetworkStream.EndRead(ar);
                    // If there are bytes to process else the connection is lost
                    if (iBytesRecieved > 0)
                    {
                        try
                        {
                            // A message came in send it to the MessageHandler
                            GetMessageHandler(this, iBytesRecieved);
                        }
                        catch
                        {
                        }
                        // Wait for a new message
                        Receive();
                    }
                    else
                        throw new Exception("Shut Down");
                }
            }
            catch (Exception)
            {
                try
                {
                    // The connection must have dropped call the CloseHandler
                    GetCloseHandler(this);
                }
                catch
                {
                }
                Dispose();
            }
        }

        /// <summary> Called when a message is sent </summary>
        /// <param name="ar"> RefType: An async result interface </param>
        private void SendComplete(IAsyncResult ar)
        {
            try
            {
                // Is the Network Stream object valid
                if (GetNetworkStream.CanWrite)
                    GetNetworkStream.EndWrite(ar);
            }
            catch (Exception)
            {
            }
        } 
        #endregion


        #region public methods
        /// <summary> Function used to connect to a server </summary>
        /// <param name="strIpAddress"> RefType: The address to connect to </param>
        /// <param name="iPort"> SimType: The Port to connect to </param>
        public void Connect(String strIpAddress, Int16 iPort)
        {
            try
            {
                if (GetNetworkStream == null)
                {
                    // Set the Ipaddress and Port
                    GetIpAddress = strIpAddress;
                    GetPort = iPort;
                    // Attempt to establish a connection
                    GetTcpClient = new TcpClient(GetIpAddress, GetPort);
                    GetNetworkStream = GetTcpClient.GetStream();
                    // Set these socket options
                    GetTcpClient.ReceiveBufferSize = 1048576;
                    GetTcpClient.SendBufferSize = 1048576;
                    GetTcpClient.NoDelay = true;
                    GetTcpClient.LingerState = new System.Net.Sockets.LingerOption(false, 0);
                    // Start to receive messages
                    Receive();
                }
            }
            catch (System.Net.Sockets.SocketException e)
            {
                throw new Exception(e.Message, e.InnerException);
            }
        }
        /// <summary> Function used to disconnect from the server </summary>
        public void Disconnect()
        {
            // Close down the connection
            if (GetNetworkStream != null)
            {
                GetNetworkStream.Close();
            }
            if (GetTcpClient != null)
            {
                GetTcpClient.Close();
            }
            // Clean up the connection state
            GetNetworkStream = null;
            GetTcpClient = null;
        }
        /// <summary> Function to send a string to the server </summary>
        /// <param name="strMessage"> RefType: A string to send </param>
        public void Send(String strMessage)
        {
            if ((GetNetworkStream != null) && (GetNetworkStream.CanWrite))
            {
                // Convert the string into a Raw Buffer
                Byte[] pRawBuffer = System.Text.Encoding.ASCII.GetBytes(strMessage);
                // Issue an asynchronus write
                GetNetworkStream.BeginWrite(pRawBuffer, 0, pRawBuffer.GetLength(0), GetCallbackWriteMethod, null);
            }
            else
            {
                throw new Exception("Socket Closed");
            }
        }
        /// <summary> Function to send a raw buffer to the server </summary>
        /// <param name="pRawBuffer"> RefType: A Raw buffer of bytes to send </param>
        public void Send(Byte[] pRawBuffer)
        {
            if ((GetNetworkStream != null) && (GetNetworkStream.CanWrite))
            {
                // Issue an asynchronus write
                GetNetworkStream.BeginWrite(pRawBuffer, 0, pRawBuffer.GetLength(0), GetCallbackWriteMethod, null);
            }
            else
            {
                throw new Exception("Socket Closed");
            }
        }
        /// <summary> Wait for a message to arrive </summary>
        public void Receive()
        {
            if ((GetNetworkStream != null) && (GetNetworkStream.CanRead))
            {
                // Issue an asynchronous read
                GetNetworkStream.BeginRead(GetRawBuffer, 0, GetSizeOfRawBuffer, GetCallbackReadMethod, null);
            }
            else
                throw new Exception("Socket Closed");
        } 
        #endregion

    }
}