Async Socket Wrapper

10/24/2011 11:05 BaussHacker#1
So I was bored and thought I would code a socket wrapper. It's a class library, but full project is available for download + an example use for a socket server.

It contains both wrapper for server and client stuff, which means it can be used for either private servers as server-socket or for a proxy.

WinAsync - This class contains all the events.

Code:
    public delegate void WinEvent(WinClient wClient);
    public delegate void WinBufferEvent(WinClient wClient, WinBuffer Buffer);
    public delegate void WinExceptionEvent(Exception Error);

    public class WinAsync
    {
        public WinEvent OnConnection;
        public WinBufferEvent OnReceive;
        public WinEvent OnDisconnection;
        public WinExceptionEvent OnError;
    }
WinBuffer - This class contains the buffer, which is send through the sockets.

Code:
    public class WinBuffer
    {
        public byte[] Buffer;

        public void Modify<T>(T Value, int Offset)
        {
            #region UInt8
            if (typeof(T) == typeof(byte))
            {
                object t = Value;
                Buffer[Offset] = (byte)t;
            }
            #endregion
            #region UInt16
            else if (typeof(T) == typeof(ushort))
            {
                object t = Value;
                ushort value = (ushort)t;
                Buffer[Offset] = (byte)(value);
                Buffer[Offset + 1] = (byte)(value >> 8);
            }
            #endregion
            #region UInt32
            else if (typeof(T) == typeof(uint))
            {
                object t = Value;
                uint value = (uint)t;
                Buffer[Offset] = (byte)(value);
                Buffer[Offset + 1] = (byte)(value >> 8);
                Buffer[Offset + 2] = (byte)(value >> 16);
                Buffer[Offset + 3] = (byte)(value >> 24);
            }
            #endregion
            #region UInt64
            else if (typeof(T) == typeof(ulong))
            {
                object t = Value;
                ulong value = (ulong)t;
                Buffer[Offset] = (byte)(value);
                Buffer[Offset + 1] = (byte)(value >> 8);
                Buffer[Offset + 2] = (byte)(value >> 16);
                Buffer[Offset + 3] = (byte)(value >> 24);
                Buffer[Offset + 4] = (byte)(value >> 32);
                Buffer[Offset + 5] = (byte)(value >> 40);
                Buffer[Offset + 6] = (byte)(value >> 48);
                Buffer[Offset + 7] = (byte)(value >> 56);
            }
            #endregion
        }

        public string ToHex()
        {
            StringBuilder sb = new StringBuilder();
            foreach (byte b in Buffer)
                sb.Append(b.ToString("X2"));
            return sb.ToString();
        }
        public override string ToString()
        {
            StringBuilder sb = new StringBuilder();
            foreach (byte b in Buffer)
            {
                sb.Append(b);
                sb.Append(" ");
            }
            sb.Length -= 1;
            return sb.ToString();
        }

        public static implicit operator WinBuffer(byte[] buffer)
        {
            return new WinBuffer() { Buffer = buffer };
        }
        public static implicit operator byte[](WinBuffer buffer)
        {
            return buffer.Buffer;
        }
    }
WinClCon - This class contains the wrapper for a client-socket.

Code:
    public class WinClCon : WinSocWrapper
    {
        public WinClCon(int BufferSize)
            : base(BufferSize)
        {
        }

        private void BeginConnect()
        {
            base.Network.Socket.BeginConnect(base.Network, new AsyncCallback(Connect_Callback), new WinClient());
        }

        public void Connect_Callback(IAsyncResult result)
        {
            try
            {
                WinClient wClient = base.Get(result, true);
                wClient.Socket.EndConnect(result);

                base.AsyncEvents.OnConnection.Invoke(wClient);

                wClient.Socket.BeginReceive(wClient.Buffer, 0, wClient.BufferLen, 0, new AsyncCallback(Receive_Callback), wClient);
            }
            catch (Exception Error)
            {
                base.AsyncEvents.OnError.Invoke(Error);
            }
        }
        public void Receive_Callback(IAsyncResult result)
        {
            try
            {
                WinClient wClient = base.Get(result, false);
                int BufferLength = wClient.Socket.EndReceive(result);
                byte[] rBuffer = new byte[BufferLength];
                Buffer.BlockCopy(wClient.Buffer, 0, rBuffer, 0, BufferLength);

                base.AsyncEvents.OnReceive.Invoke(wClient, rBuffer);

                wClient.Socket.BeginReceive(wClient.Buffer, 0, wClient.BufferLen, 0, new AsyncCallback(Receive_Callback), wClient);
            }
            catch (Exception Error)
            {
                base.AsyncEvents.OnError.Invoke(Error);
            }
        }
    }
WinClient - This class contains the socket-client, which the wrappers will use. It can either be the server or the client, depending on if it's a client or a server.

Code:
    public class WinClient
    {
        public System.Net.Sockets.Socket Socket;
        public WinBuffer Buffer;
        public int BufferLen
        {
            get
            {
                return Buffer.Buffer.Length;
            }
        }
        public string IP
        {
            get
            {
                try
                {
                    return (this.Socket.RemoteEndPoint as System.Net.IPEndPoint).Address.ToString();
                }
                catch { return "127.0.0.1"; }
            }
        }
        public bool Connected
        {
            get { return Socket.Connected; }
        }
        public void Disconnect()
        {
            Socket.Disconnect(false);
        }
        public void Send(WinBuffer Buffer)
        {
            byte[] sBuffer = new byte[Buffer.Buffer.Length];
            System.Buffer.BlockCopy(Buffer, 0, sBuffer, 0, Buffer.Buffer.Length);
            Socket.Send(sBuffer);
        }
        public void EndAccept(System.Net.Sockets.Socket socket, IAsyncResult result)
        {
            Socket = socket.EndAccept(result);
        }
        public int EndReceive(IAsyncResult result, out System.Net.Sockets.SocketError SE)
        {
            return Socket.EndReceive(result, out SE);
        }
    }
WinNetwork - This class contains network information and the global socket for each wrapper.

Code:
    public class WinNetwork
    {
        public System.Net.Sockets.Socket Socket;
        public string Address;
        public int Port;

        public void Bind()
        {
            Socket.Bind(this);
        }
        public void Connect()
        {
            Socket.Connect(this);
        }

        public static implicit operator System.Net.IPEndPoint(WinNetwork Network)
        {
            return new System.Net.IPEndPoint(System.Net.IPAddress.Parse(Network.Address), Network.Port);
        }
    }
WinSocWrapper - This class contains the wrapper both the server and the client socket wrappers are using.

Code:
    public enum WinProtocol : byte
    {
        TCP = 0,
        UDP = 1
    }

    public class WinSocWrapper
    {
        public WinAsync AsyncEvents;
        public WinNetwork Network;
        public int BufferSize;

        public WinSocWrapper(int BufferSize)
        {
            this.BufferSize = BufferSize;
        }

        public void DisconnectSocket()
        {
            Network.Socket.Disconnect(false);
        }
        public void Listen(WinProtocol Protocol, int Backlog)
        {
            if (Protocol == WinProtocol.TCP)
            {
                Network.Socket = new System.Net.Sockets.Socket(System.Net.Sockets.AddressFamily.InterNetwork,
                    System.Net.Sockets.SocketType.Stream,
                    System.Net.Sockets.ProtocolType.Tcp);
            }
            else
            {
                Network.Socket = new System.Net.Sockets.Socket(System.Net.Sockets.AddressFamily.InterNetwork,
                    System.Net.Sockets.SocketType.Stream,
                    System.Net.Sockets.ProtocolType.Udp);
            }

            Network.Bind();
            Network.Socket.Listen(Backlog);
        }

        protected WinClient Get(IAsyncResult result, bool retnull)
        {
            try
            {
                return result.AsyncState as WinClient;
            }
            catch (Exception Error)
            {
                if (!retnull)
                    this.AsyncEvents.OnError.Invoke(Error);
                return null;
            }
        }
    }
WinSvCon - This class contains the wrapper for a server-socket.

Code:
    public class WinSvCon : WinSocWrapper
    {
        public WinSvCon(int BufferSize)
            : base(BufferSize)
        {
        }

        public void BeginAccept()
        {
            base.Network.Socket.BeginAccept(new AsyncCallback(Accept_Callback), new WinClient());
        }

        public void BeginReceive(WinClient client)
        {
            client.Socket.BeginReceive(client.Buffer, 0, base.BufferSize, System.Net.Sockets.SocketFlags.None, new AsyncCallback(Receive_Callback), client);
        }

        public void Accept_Callback(IAsyncResult result)
        {
            try
            {
                WinClient wClient = base.Get(result, true);
                wClient.Buffer = new byte[base.BufferSize];

                bool accepted;
                if ((accepted = Accepted(wClient, result)) == true)
                    AsyncEvents.OnConnection.Invoke(wClient);

                BeginAccept();

                if (accepted)
                    BeginReceive(wClient);
            }
            catch { }
        }
        private bool Accepted(WinClient wClient, IAsyncResult result)
        {
            try
            {
                wClient.EndAccept(base.Network.Socket, result);
                return true;
            }
            catch
            {
                return false;
            }
        }

        public void Receive_Callback(IAsyncResult result)
        {
            WinClient wClient = base.Get(result, false);
            if (wClient != null)
            {
                try
                {
                    if (wClient.Connected)
                    {
                        System.Net.Sockets.SocketError error;
                        int BufferLength = wClient.EndReceive(result, out error);

                        if (error == System.Net.Sockets.SocketError.Success)
                        {
                            if (BufferLength > 0)
                            {
                                byte[] rBuffer = new byte[BufferLength];
                                Buffer.BlockCopy(wClient.Buffer, 0, rBuffer, 0, wClient.BufferLen);
                                base.AsyncEvents.OnReceive.Invoke(wClient, rBuffer);
                                BeginReceive(wClient);
                                return;
                            }
                        }
                    }

                    base.AsyncEvents.OnDisconnection.Invoke(wClient);
                }
                catch
                {
                    base.AsyncEvents.OnDisconnection.Invoke(wClient);
                }
            }
            else
            {
                base.AsyncEvents.OnDisconnection.Invoke(wClient);
            }
        }
    }
Server Example:
Code:
    class Program
    {
        static void Main(string[] args)
        {
            WinSvCon socket = new WinSvCon(1024);//Creating a new socket with the default buffersize as 1024

            socket.AsyncEvents = new WinAsync();//Creating a new asyncevent class
            /* Setting the events */
            socket.AsyncEvents.OnConnection = new WinEvent(NewConnection);
            socket.AsyncEvents.OnReceive = new WinBufferEvent(NewReceive);
            socket.AsyncEvents.OnDisconnection = new WinEvent(NewDisconnection);
            socket.AsyncEvents.OnError = new WinExceptionEvent(NewError);

            socket.Network = new WinNetwork();//Creating a new network
            socket.Network.Address = "127.0.0.1";//The network address
            socket.Network.Port = 4444;//The network port

            socket.Listen(WinProtocol.TCP, 100);//Starting to listen connections from a tcp protocol with the backlog 100
            socket.BeginAccept();//Beginning to accept connections

            Console.WriteLine("Server has started...");

            while (true)
                Console.ReadLine();
        }

        static void NewConnection(WinClient wClient)
        {
            Console.WriteLine("New connection from {0}.", wClient.IP);
        }
        static void NewReceive(WinClient wClient, WinBuffer Buffer)
        {
            Console.WriteLine("New data from {0}. Length: {1}.", wClient.IP, Buffer.Buffer.Length);
            wClient.Send(Buffer);
            Console.WriteLine("Send data back to client...");
        }
        static void NewDisconnection(WinClient wClient)
        {
            if (wClient != null)
            {
                Console.WriteLine("New disconnection from {0}.", wClient.IP);
            }
            else
            {
                Console.WriteLine("New disconnection from unknown client.");
            }
        }
        static void NewError(Exception Error)
        {
            Console.WriteLine(Error.ToString());
        }
    }
[Only registered and activated users can see links. Click Here To Register...]

Ref:
[Only registered and activated users can see links. Click Here To Register...]
[Only registered and activated users can see links. Click Here To Register...]
10/24/2011 11:23 Korvacs#2
Should be noted that despite the heavy use of WinSoc, which i interpreted to mean WinSock, it infact is entirely managed and never touches WinSock.
10/24/2011 11:26 BaussHacker#3
Quote:
Originally Posted by Korvacs View Post
Should be noted that despite the heavy use of WinSoc, which i interpreted to mean WinSock, it infact is entirely managed and never touches WinSock.
Just my namespace.
10/24/2011 11:27 IAmHawtness#4
Looks nice, I don't quite understand the whole
Code:
public void Modify<T>(T Value, int Offset)
though. Why not just make more overloaded methods which take different types of input, instead of checking the type of the parameter on every call?

Code:
public void Modify(byte value, int Offset)
public void Modify(uint value, int Offset)
public void Modify(ushort value, int Offset)

..etc
10/24/2011 11:29 BaussHacker#5
Quote:
Originally Posted by IAmHawtness View Post
Looks nice, I don't quite understand the whole
Code:
public void Modify<T>(T Value, int Offset)
though. Why not just make more overloaded methods which take different types of input, instead of checking the type of the parameter on every call?

...
I actually don't know :P But either way, it's an open source now, so if people want to make changes and improvements they can go ahead.
10/24/2011 13:05 Chalkie#6
hw i usa thas aimpoot?
10/24/2011 13:16 BaussHacker#7
Quote:
Originally Posted by Chalkie View Post
hw i usa thas aimpoot?
Code:
void impoot(bool festblade)
{
blayer noob = getblyerframscren();


while (inscren(noob))
{
if (festblade)
useskell(1045, noob);
else
useskell(1046, noob);
}

}
10/24/2011 17:49 nTL3fTy#8
Quote:
Originally Posted by BaussHacker View Post
Code:
public void Modify<T>(T Value, int Offset)
For this method, instead of using all those typeof calls, you can switch on Type.GetTypeCode(typeof(T)), which returns a TypeCode enum.

Code:
switch (Type.GetTypeCode(typeof(T))
{
    case TypeCode.Boolean: ...
    case TypeCode.Byte: ...
}
You can also use a mixture of the two:
Code:
if (typeof(T).IsEnum) { ... }

switch (Type.GetTypeCode(typeof(T))
{
    ...
}
11/11/2011 08:18 xmen01235#9
I think my socket wrapper in my siggy is simpler than this one. :D