locked
Creating a socket server RRS feed

  • Question

  • Hello I am looking to create a socket listening server.  So far I have a simple interface with text boxes for inputting the client who will be sending the sockets data, and then i have a rich text box to put whatever data is received.  I am trying to create a background worker that runs once a LISTEN button is pressed.  I want it to just continously update the text box as data is received while running in the background.  I cant figure out how to add the listening function to the back ground however and get it to pass the data to the rich text box.  Here is some of what I have.  Any help would be greatly appreciated

    This is my static method for listening for a socket:

     public static String receiveString(String IP,int port)
            {
                try
                {
                    Socket socketSender = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                    System.Net.IPAddress serverIP = System.Net.IPAddress.Parse(IP);
                    System.Net.IPEndPoint remoteEP = new System.Net.IPEndPoint(serverIP,port);
                    socketSender.Connect(remoteEP);
                    byte[] recData = new byte[250];
                    socketSender.Receive(recData);
                    String recString = Encoding.UTF8.GetString(recData);
                    socketSender.Close();
                    return recString;
                }
                catch
                {
                    return "No Response \n";
                }
            }

    This method starts the background worker:

            private void button2_Click(object sender, EventArgs e)
            {
                backgroundWorker1.RunWorkerAsync();
            }

    Here are the background worker methods:

           private void DoWork(object sender, DoWorkEventArgs e)
            {
                while (true)
                {
                    String response = Utilities.receiveString(ipBox.Text,6112);
                    backgroundWorker1.ReportProgress(0, response);
                }
            }

            private void ProgressChanged(object sender, ProgressChangedEventArgs e)
            {
                responseBox.Text += e.ToString();
                responseBox.Text += "Reported!";
            }  


    Sunday, June 1, 2008 3:30 PM

All replies

  • Although you perhaps can do it with the background worker, I suggest you get rid of it because if puts a lot of fog into your understanding. Background workers are useful when you need to keep track of the process in the form of a progress control. For isntance you are downloading a large batch of files and you have no idea if your set up is working or not because everything is silent. It may take an hour. Having a background worker gives you a chance to observe the process in motion as it goes. It gives you peace of mind.

    public class AsynchronousSocketListener
    {

        public
    static ManualResetEvent allDone = new ManualResetEvent ( false );
        public
    AsynchronousSocketListener ( ){}

        public
    static void StartListening ( )
        {
            byte
    [] bytes = new Byte[1024]; // Data buffer for incoming data.System.Net.IPAddress ipAddress = System.Net.IPAddress.Parse ( "127.0.0.1" );
            IPEndPoint localEndPoint
    = new IPEndPoint ( ipAddress, 19001 );
            // Create a TCP/IP socket.
            Socket listener = new Socket ( AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp );
            // Bind the socket to the local endpoint and listen for incoming connections.
            try
            {
                listener.Bind
    ( localEndPoint );
                listener.Listen
    ( 100 );
                while
    ( true )
                {
                    allDone.Reset
    ( ); // Set the event to nonsignaled state.
                    Console.WriteLine ( "Waiting for a connection..." );
                    listener.BeginAccept
    ( new AsyncCallback ( AcceptCallback ), listener ); // Start an asynchronous socket to listen for connections.
                    allDone.WaitOne ( ); // Wait until a connection is made before continuing.
                }
            }
            catch
    ( Exception e )
            {
                Console.WriteLine
    ( e.ToString ( ) );
            }
            Console.WriteLine
    ( "\nPress ENTER to continue..." );
            Console.Read
    ( );
        }
    // StartListening

        public static void AcceptCallback ( IAsyncResult ar )
        {
            // Signal the main thread to continue.
            allDone.Set ( );
            Socket listener
    = ( Socket )ar.AsyncState; // Get the socket that handles the client request.
            Socket handler = listener.EndAccept ( ar );
            StateObject state
    = new StateObject ( ); // Create the state object.state.workSocket = handler;
            handler.BeginReceive
    ( state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback ( ReadCallback ), state );
        } 
    // AcceptCallback

        public static void ReadCallback ( IAsyncResult ar )
        {
            String content
    = String.Empty;
            // Retrieve the state object and the handler socket
            // from the asynchronous state object.
            StateObject state = ( StateObject )ar.AsyncState;
            Socket handler
    = state.workSocket;
            // an existing connection was forceably closed by remote host 7/23/2007
    int bytesRead = handler.EndReceive ( ar ); // Read data from the client socket. 
            if ( bytesRead > 0 )
            {
                // There might be more data, so store the data received so far.
                state.sb.Append ( Encoding.ASCII.GetString ( state.buffer, 0, bytesRead ) );
                // Check for end-of-file tag. If it is not there, read more data.
                content = state.sb.ToString ( );
                if
    ( content.IndexOf ( "<EOF>" ) > -1 )
                {
                    // All the data has been read from the client. Display it on the console.
                    Console.WriteLine ( "\n {1}", content.Length, content.Substring(0,content.IndexOf ("<EOF>")) );
                    string
    confirmation = "Order Received<EOF>";
                    Send
    ( handler, confirmation ); // Send Confirmation
                    // Send ( handler, content ); 
                    // Echo the data back to the client.
    }
                else
                {
                   // Not all data received. Get more.
                    handler.BeginReceive ( state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback ( ReadCallback ), state );
                }
            }
        }
    // ReadCallback

        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 );
        }
    // Send

        private static void SendCallback ( IAsyncResult ar )
        {
            try
            {
                Socket handler
    = ( Socket )ar.AsyncState; // Retrieve the socket from the state object.
                int bytesSent = handler.EndSend ( ar ); // Complete sending the data to the remote device.
                handler.Shutdown ( SocketShutdown.Both );
                handler.Close
    ( );
                AsynchronousSocketListener clss
    = new AsynchronousSocketListener ( );
                clss.playSimpleSound
    ( );
            }
            catch
    ( Exception e )
            {
                Console.WriteLine
    ( e.ToString ( ) );
            }
        }
    // SendCallback
    }


    AlexB
    Sunday, June 1, 2008 4:48 PM
  • I have no idea how to work with that code you posted.  Also i need the socket server to be continously listening because it is for an instant messenger program I am creating.
    Sunday, June 1, 2008 5:53 PM
  • The best way of completing what you want to do is to as  Alex say, use Async Sockets.  There are lots of examples on MSDN how to accomplish this, or you could try codeproject.com where there are again lots of examples and downloadable code that you can use as a start point for your own application.

    I have written a Server/Client application recently and using Async Sockets is by far the best way to do things.  It will accomplish what you are after very easily.  Let me know how you get on and if you need I can provide some of the code that I used recently to get you going.

    Regards

    Mark
    Sunday, June 1, 2008 8:48 PM
  • If you have no idea how to use it you should read on the subject. It is NOT a simple concept for a beginner. The code I posted is my working code. It does exactly what your specification is: it listens to the incoming messages continuously.

    If you have any specific questions you should ask them specifically. Nobody will be able to widen your horizons here. There is plenty of stuff on the web.

    This listener is used for communications between app domains and therefore it is hooked to a local host. If your server is on the network you should change the IP address.

    I forgot to post a supplementary class: StateObject. Here it is.

    public class StateObject
    {
        public const int BufferSize = 4195304; // 4MBts, you can reduce it drastically
        public byte[] buffer = new byte[BufferSize]; // Receive buffer.
        public Socket workSocket = null; // Client socket.
    } // class StateObject


    As Mark mentioned there are numerous examples on MSDN but they are all pretty much clones of a single source: MSDN code sample posted years ago. This is where I got mine too. I cannot file a patent application.
    AlexB
    Monday, June 2, 2008 12:22 AM
  • Have a look here for a good description on the differences between synchronous and asynchronous socket programming,

    http://www.codeguru.com/csharp/csharp/cs_network/sockets/article.php/c7695/

    http://www.developerfusion.co.uk/show/3997/

    http://www.devarticles.com/c/a/C-Sharp/Socket-Programming-in-C-Part-I/

    These articles helped me a great deal when I first started looking at Socket programming a few months ago

    MarkW


    Monday, June 2, 2008 12:17 PM
  • Although you perhaps can do it with the background worker, I suggest you get rid of it because if puts a lot of fog into your understanding. Background workers are useful when you need to keep track of the process in the form of a progress control. For isntance you are downloading a large batch of files and you have no idea if your set up is working or not because everything is silent. It may take an hour. Having a background worker gives you a chance to observe the process in motion as it goes. It gives you peace of mind.

    publicclass AsynchronousSocketListener
    {

        public
    staticManualResetEvent allDone=newManualResetEvent ( false);
        public
    AsynchronousSocketListener( ){}

        public
    staticvoidStartListening( )
        {
            byte
    [] bytes=newByte[1024]; // Data buffer for incoming data.System.Net.IPAddress ipAddress =System.Net.IPAddress.Parse( "127.0.0.1");
            IPEndPoint localEndPoint
    =newIPEndPoint ( ipAddress, 19001 );
            // Create a TCP/IP socket.
            Socket listener=newSocket ( AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp );
            // Bind the socket to the local endpoint and listen for incoming connections.
            try
            {
                listener.Bind
    ( localEndPoint);
                listener.Listen
    ( 100 );
                while
    ( true)
                {
                    allDone.Reset
    ( ); // Set the event to nonsignaled state.
                    Console.WriteLine( "Waiting for a connection...");
                    listener.BeginAccept
    ( newAsyncCallback( AcceptCallback), listener ); // Start an asynchronous socket to listen for connections.
                    allDone.WaitOne( ); // Wait until a connection is made before continuing.
                }
            }
            catch
    ( Exception e)
            {
                Console.WriteLine
    ( e.ToString( ) );
            }
            Console.WriteLine
    ( "\nPress ENTER to continue...");
            Console.Read
    ( );
        }
    // StartListening

        publicstaticvoidAcceptCallback( IAsyncResult ar )
        {
            // Signal the main thread to continue.
            allDone.Set( );
            Socket listener
    =( Socket )ar.AsyncState; // Get the socket that handles the client request.
            Socket handler=listener.EndAccept( ar);
            StateObject state
    =newStateObject ( ); // Create the state object.state.workSocket = handler;
            handler.BeginReceive
    ( state.buffer, 0, StateObject.BufferSize, 0, newAsyncCallback( ReadCallback), state );
        } 
    // AcceptCallback

        publicstaticvoidReadCallback( IAsyncResult ar)
        {
            String content
    =String.Empty;
            // Retrieve the state object and the handler socket
            // from the asynchronous state object.
            StateObject state=( StateObject )ar.AsyncState;
            Socket handler
    =state.workSocket;
            // an existing connection was forceably closed by remote host 7/23/2007
    intbytesRead=handler.EndReceive( ar ); // Read data from the client socket. 
            if( bytesRead> 0 )
            {
                // There might be more data, so store the data received so far.
                state.sb.Append ( Encoding.ASCII.GetString ( state.buffer, 0, bytesRead ) );
                // Check for end-of-file tag. If it is not there, read more data.
                content=state.sb.ToString( );
                if
    ( content.IndexOf( "<EOF>") > -1 )
                {
                    // All the data has been read from the client. Display it on the console.
                    Console.WriteLine( "\n {1}", content.Length, content.Substring(0,content.IndexOf("<EOF>")) );
                    string
    confirmation="Order Received<EOF>";
                    Send
    ( handler, confirmation ); // Send Confirmation
                    // Send ( handler, content ); 
                    // Echo the data back to the client.
    }
                else
                {
                   // Not all data received. Get more.
                    handler.BeginReceive ( state.buffer, 0, StateObject.BufferSize, 0, newAsyncCallback( ReadCallback), state );
                }
            }
        }
    // ReadCallback

        privatestaticvoidSend( 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, newAsyncCallback( SendCallback), handler);
        }
    // Send

        privatestaticvoidSendCallback( IAsyncResult ar )
        {
            try
            {
                Socket handler
    =( Socket )ar.AsyncState; // Retrieve the socket from the state object.
                intbytesSent=handler.EndSend( ar ); // Complete sending the data to the remote device.
                handler.Shutdown( SocketShutdown.Both);
                handler.Close
    ( );
                AsynchronousSocketListener clss
    =newAsynchronousSocketListener( );
                clss.playSimpleSound
    ( );
            }
            catch
    ( Exception e)
            {
                Console.WriteLine
    ( e.ToString ( ) );
            }
        }
    // SendCallback
    }


    AlexB

    The question from thread started obviously describe that the the application will use gui. the code that you paste is copied from msdn async sample which was made for command line. the line "allDone.WaitOne( ); // Wait until a connection is made before continuing." obviously lock the thread which is bad for gui app. you answer did not answer the question and please stop pretending that it does. the reason that thread starter uses background worker is to listen in background without locking the thread. most async sample deal with async listening (if you understand what i mean) not async server in gui environment.

    i believe what thread started really wants is how to create listening server in gui app.

    Monday, December 31, 2012 3:19 AM