Public feed #527558

SocketServer

public text v1 · immutable
Raw Edit
·published 2007-06-01 10:45 UTC
rendered paste body
using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Windows.Forms;
using System.IO;
using System.Xml.Serialization;
namespace ITransfer
{
    public class SocketServer
    {
        //Database
        //Singleton pattern database to write all incoming objects to the DB.
        public static Database db = Database.Instance;
        
        // Thread signal.
        // Triggers the main thread to continue (listening for clients)
        // when the previous incoming connection request has been handled.
        public static ManualResetEvent allDone = new ManualResetEvent(false);

        //Constructor
        public SocketServer()
        {
            db.Connect();
        }
        //Listens for a new connection on the main thread.
        public static void ListenNewConnection()
        {
            // Data buffer for incoming data.
            byte[] bytes = new Byte[1024];

            #region Create Listener Socket
            // Establish the local endpoint for the socket.
            // The DNS name of the computer
            IPHostEntry ipHostInfo = Dns.Resolve(Dns.GetHostName());
            IPAddress ipAddress = ipHostInfo.AddressList[0];
            IPEndPoint localEndPoint = new IPEndPoint(ipAddress, 11000);

            // Create a TCP/IP socket.
            Socket listener = new Socket(AddressFamily.InterNetwork,
                SocketType.Stream, ProtocolType.Tcp);
            #endregion
            // Bind the socket to the local endpoint and listen for incoming connections.
            try
            {
                listener.Bind(localEndPoint);
                listener.Listen(100);

                while (true)
                {
                    // Set the event to nonsignaled state.
                    allDone.Reset();

                    // Start an asynchronous socket to listen for connections.
                    
                    /*Console.WriteLine("Waiting for a connection...");*/
                    listener.BeginAccept(
                        new AsyncCallback(AcceptCallback),
                        listener);

                    // Wait until a connection is made before continuing.
                    allDone.WaitOne();
                }

            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                Application.Exit();
            }
        }
        //Creates a new socket for the incoming connection of the main thread.
        public static void AcceptCallback(IAsyncResult ar)

        {
            // Signal the main thread to continue.
            allDone.Set();

            // Get the socket that handles the client request.
            Socket listener = (Socket)ar.AsyncState;
            Socket handler = listener.EndAccept(ar);

            // Create the state object.
            StateObject state = new StateObject();
            state.OperationState = "INI";
            state.workSocket = handler;
            Send(state.workSocket, "HI");
            handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
                new AsyncCallback(ReadCallback), state);
        }
        //Receives data from a certain socket.
        public static void ReadCallback(IAsyncResult ar)
        {
            String content = String.Empty;
            int bytesRead;

            // Retrieve the state object and the handler socket
            // from the asynchronous state object.
            StateObject state = (StateObject)ar.AsyncState;
            Socket handler = state.workSocket;

            switch(state.OperationState)
            {
                #region INI
                case "INI":
                       //SENDED "HI" TO THE CLIENT
                       //EXPECTING "HI" AS RETURN
                    bytesRead = handler.EndReceive(ar);
                    if (bytesRead > 0)
                    {
                        state.sb.Append(Encoding.ASCII.GetString(
                               state.buffer, 0, bytesRead));
                        string clientReply = state.sb.ToString();
                        if (clientReply == "HI")
                        {
                            //A proper connection has been made. 
                            //Request the number of files to receive.
                            state.sb.Remove(0, state.sb.Length);
                            state.OperationState = "NUM_FILE_REQUEST";
                            Send(handler, "NF");
                            handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
                new AsyncCallback(ReadCallback), state);
                        }
                    }
                    break;
                #endregion
                #region NUM_FILE_REQUEST
                case "NUM_FILE_REQUEST":

                    //SENDED "NF" TO THE CLIENT
                    //EXPECTING INT AS RETURN
                    bytesRead = handler.EndReceive(ar);
                    if (bytesRead > 0)
                    {
                        
                        state.sb.Append(Encoding.ASCII.GetString(
                               state.buffer, 0, bytesRead));
                        string clientReply = state.sb.ToString();
                        int numFiles = int.Parse(clientReply);
                        if (numFiles > 0)
                        {
                            //There are files that need to be sent. 
                            //Request the transfer.
                            state.sb.Remove(0, state.sb.Length);
                            state.NumberOfFiles = numFiles;
                            state.OperationState = "SEND_FILESIZE";
                            Send(handler, "SF");
                            handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
                new AsyncCallback(ReadCallback), state);
                        }
                        else
                        {
                            //else there are no files to be received. close the connection.
                            handler.Shutdown(SocketShutdown.Both);
                            handler.Close();
                        }

                    }

                    break;
                #endregion
                #region SEND_FILESIZE
                case "SEND_FILESIZE":
                    //SENDED 'SF' TO THE CLIENT
                    //EXPECTING FILESIZE AS RETURN
                    bytesRead = handler.EndReceive(ar);
                    if (bytesRead > 0)
                    {
                        //Get the fileSize
                        state.sb.Append(Encoding.ASCII.GetString(
                               state.buffer, 0, bytesRead));
                        string clientReply = state.sb.ToString();
                        long fileSize = long.Parse(clientReply);

                        //set the filesize in the state
                        state.currentFileSize = fileSize;
                        
                        //clear the string in the state
                        state.sb.Remove(0, state.sb.Length);
                        //Set the state to GO FILE
                        state.OperationState = "GO_FILE";
                        Send(handler, "GF");
                        //Start receiving the file
                        handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
                new AsyncCallback(ReadCallback), state);
                    }

                    break;
                #endregion
                #region GO_FILE
                case "GO_FILE":
                    //SENDED 'GF' TO THE CLIENT
                    //EXPECTING FILE AS RETURN

                    bytesRead = handler.EndReceive(ar);
                    if (bytesRead > 0)
                    {
                        state.memstream.Write(state.buffer, 0, bytesRead);
                        //file is complete
                        if (state.memstream.Length >= state.currentFileSize)
                        {

                            XmlSerializer xs = new XmlSerializer(typeof(KioskInfo));
                            state.memstream.Seek(0, SeekOrigin.Begin);
                            KioskInfo s = (KioskInfo)xs.Deserialize(state.memstream);
                            
                            //HERE IS WHERE THE FILE HANDLING OCCURS
                            //WRITING TO FILE
                            //WRITING TO DATABASE etc.
                            db.addEntry(s.NaamPC, s.Datum, s.Uur);
                            //MessageBox.Show(s.NaamPC);
                            /*
                            FileStream fs = new FileStream("Test.txt", FileMode.Create);
                            BinaryWriter w = new BinaryWriter(fs);
                            w.Write(state.memstream.ToArray(),0,state.memstream.ToArray().Length);
                            w.Close();
                            fs.Close();
                            */

                            state.memstream.Flush();
                            state.memstream.Close();
                            state.memstream = new MemoryStream();
                            Send(handler, "NX");

                            state.NumberOfFiles--;

                            //if there are  more files, receive the next filesize otherwise
                            //close the socket
                            if (state.NumberOfFiles == 0)
                            {
                                handler.Shutdown(SocketShutdown.Both);
                                handler.Close();
                            }
                            else
                            {
                                state.OperationState = "SEND_FILESIZE";
                                handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
                    new AsyncCallback(ReadCallback), state);
                            }
                        }
                        //file isn't complete yet
                        else
                        {
                            //CONTINUE LISTENING FOR DATA
                            handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
                new AsyncCallback(ReadCallback), state);
                        }
                    }

                    break;
                #endregion
            }
            
        }
        //Start sending data to a certain socket.
        private static void Send(Socket handler, String data)
        {
            // Convert the string data to byte data using ASCII encoding.
            byte[] byteData = Encoding.ASCII.GetBytes(data);

            // Begin sending the data to the remote device.
            handler.BeginSend(byteData, 0, byteData.Length, 0,
                new AsyncCallback(SendCallback), handler);
        }
        //ending the send to a certain socket.
        private static void SendCallback(IAsyncResult ar)
        {
            try
            {
                // Retrieve the socket from the state object.
                Socket handler = (Socket)ar.AsyncState;

                // Complete sending the data to the remote device.
                int bytesSent = handler.EndSend(ar);
                Console.WriteLine("Sent {0} bytes to client.", bytesSent);

                //handler.Shutdown(SocketShutdown.Both);
               //handler.Close();

            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
            }
        }


    }
}