All pastes #11717 Raw Edit

tobz

public text v1 · immutable
#11717 ·published 2005-05-14 03:57 UTC
rendered paste body
using System;
using System.Diagnostics;
using System.Text;
using System.Net;
using System.Net.Sockets;

namespace DOLInfoServer
{
    public class ServerComponent : IServer
    {
        public AsyncCallback pfnWorkerCallBack;
        private Socket m_mainSocket;
        private Socket[] m_workerSocket = new Socket[10];
        private int m_clientCount = 0;
        private static int port = 10500;
        private IPEndPoint ipLocal = new IPEndPoint(IPAddress.Any, port);
        private string sessionPassword;
        private string keyHeader = "####";
        private UTF8Encoding enc = new UTF8Encoding();

        public static void Main(string[] args)
        {
            ServerComponent srvr = new ServerComponent();
            srvr.StartServer();
        }

        public void StartServer()
        {
            Console.WriteLine("DOLInfoServer started! Currently configured to listen on [all] interfaces, at port 10500.");
            m_mainSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

            Console.WriteLine("Binding socket....");
            m_mainSocket.Bind(ipLocal);
            Console.WriteLine("Placing socket in listening state....");
            m_mainSocket.Listen(4);
            Console.WriteLine("Waiting for connection....");
            m_mainSocket.BeginAccept(new AsyncCallback(OnClientConnect), null);
            Console.ReadLine();
        }
        public void OnClientConnect(IAsyncResult asyn)
        {
            try
            {
                // Here we complete/end the BeginAccept() asynchronous call
                // by calling EndAccept() - which returns the reference to
                // a new Socket object
                m_workerSocket[m_clientCount] = m_mainSocket.EndAccept(asyn);
                // Let the worker Socket do the further processing for the 
                // just connected client
                WaitForData(m_workerSocket[m_clientCount]);
                // Now increment the client count
                ++m_clientCount;
                // Display this client connection as a status message on the GUI	
                Console.WriteLine("New connection, sending encryption key.");
                AfterClientConnect(m_workerSocket[m_clientCount]);

                // Since the main Socket is now free, it can go back and wait for
                // other clients who are attempting to connect
                m_mainSocket.BeginAccept(new AsyncCallback(OnClientConnect), null);
            }
            catch (ObjectDisposedException)
            {
                System.Diagnostics.Debugger.Log(0, "1", "\n OnClientConnection: Socket has been closed\n");
            }
            catch (SocketException)
            {
            }

        }
        public class SocketPacket
        {
            public Socket m_currentSocket;
            public byte[] dataBuffer = new byte[1];
        }

        public void AfterClientConnect(Socket dataSocket)
        {
            // compute our key from endpoint and our guid, something fancy :p
            string theirEndpoint = ((IPEndPoint)dataSocket.RemoteEndPoint).Address.ToString();
            string ourGuid = System.Guid.NewGuid().ToString().Substring(0, theirEndpoint.Length);

            for (int i = 0; i < ourGuid.Length; i++)
            {
                sessionPassword += theirEndpoint[i];
                sessionPassword += ourGuid[i];
            }

            // we got our password, now send it over.
            // from now on, everything will be encrypted.
            dataSocket.Send(enc.GetBytes(keyHeader + sessionPassword));
        }

        public void SendInfo(Socket dataSocket) { }

        public void DataReceived(string data, Socket dataSocket)
        {
            if (data.StartsWith("encryption acknowleded"))
            {
                Console.WriteLine("encryption is in place! :D");
                SendInfo(dataSocket);
            }
            else
            {
                Console.WriteLine("encryption failed :(");
                dataSocket.Close();
            }
        }

        // Start waiting for data from the client
        public void WaitForData(Socket dataSocket)
        {
            try
            {
                if (pfnWorkerCallBack == null)
                {
                    // Specify the call back function which is to be 
                    // invoked when there is any write activity by the 
                    // connected client
                    pfnWorkerCallBack = new AsyncCallback(OnDataReceived);
                }
                SocketPacket socketPkt = new SocketPacket();
                socketPkt.m_currentSocket = dataSocket;
                // Start receiving any data written by the connected client
                // asynchronously
                dataSocket.BeginReceive(socketPkt.dataBuffer, 0,
                                   socketPkt.dataBuffer.Length,
                                   SocketFlags.None,
                                   pfnWorkerCallBack,
                                   socketPkt);
            }
            catch (SocketException)
            {
            }

        }
        // This the call back function which will be invoked when the socket
        // detects any client writing of data on the stream
        public void OnDataReceived(IAsyncResult asyn)
        {
            try
            {
                SocketPacket socketData = (SocketPacket)asyn.AsyncState;

                int iRx = 0;
                iRx = socketData.m_currentSocket.EndReceive(asyn);
                char[] chars = new char[iRx + 1];

                System.Text.Decoder d = System.Text.Encoding.UTF8.GetDecoder();
                int charLen = d.GetChars(socketData.dataBuffer, 0, iRx, chars, 0);
                string szData = new System.String(chars);

                string decodedData = Crypto.Decrypt(szData, sessionPassword);
                DataReceived(decodedData, socketData.m_currentSocket);

                // Continue the waiting for data on the Socket
                WaitForData(socketData.m_currentSocket);
            }
            catch (ObjectDisposedException)
            {
                System.Diagnostics.Debugger.Log(0, "1", "\nOnDataReceived: Socket has been closed\n");
            }
            catch (SocketException)
            {
            }
        }

        void CloseSockets()
        {
            if (m_mainSocket != null)
            {
                m_mainSocket.Close();
            }
            for (int i = 0; i < m_clientCount; i++)
            {
                if (m_workerSocket[i] != null)
                {
                    m_workerSocket[i].Close();
                    m_workerSocket[i] = null;
                }
            }
        }
    }
}