< Asynchronous & C++ I/O Program Example | Main | VB .NET Asynchronous I/O & C++ Thread and Network I/O Examples >

 


 

Chapter 3 Part 8:

Threading and the Asynchronous Pattern

 

 

What do we have in this chapter 3 Part 8?

  1. C# Asynchronous I/O Program Example

 

 

C# Asynchronous I/O Program Example

 

Create a new console application project. You can use the project and solution name as in the following Figure if you want.

 

C# Asynchronous I/O Program Example - a new console application project creation

 

Add the following codes and you can discard the comment parts.

 

using System;

using System.Net;

using System.Net.Sockets;

 

// <summary>

// This sample is a revision of the NetworkStream Server sample in

// Chapter 02. This server is designed to accept multiple connections

// and demonstrates how to use the NetworkStream class to perform IO between

// 2 sockets. This application performs IO asynchronously by using the BeginXXX

// and EndXXX asynchronous IO pattern. The original sample only accepted 1

// connection and processed IO synchronously. Because this application processes

// IO asynchronously, the application is capable of handling multiple connections

// at the same time.

//

// To run this sample, simply just run the program without parameters and

// it will listen for a client connection on TCP port 5150. If you want to

// use a different port than 5150 then you can optionally supply a command

// line parameter "/port <port number>" and the listening socket will use

// your port instead.

// </summary>

namespace AsyncNetworkIOCS

{

    class Program

    {

        // <summary>

        // The main entry point for the application.

        // </summary>

        [STAThread]

        static void Main(string[ ] args)

        {

            int Port = 5150;

 

            // Parse command line arguments if any

            for (int i = 0; i < args.Length; i++)

            {

                try

                {

                    if (String.Compare(args[i], "/port", true) == 0)

                    {

                        // The port on which the server is listening

                        Port = System.Convert.ToInt32(args[++i].ToString());

                    }

                }

                catch (System.IndexOutOfRangeException)

                {

                    Console.WriteLine("Usage: Receiver [/port <port number>]");

                    return;

                }

            }

 

            Socket ServerSocket = null;

            Socket ListeningSocket = null;

 

            try

            {

                // Setup a listening Socket to await a connection from a peer socket.

                ListeningSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);

                Console.WriteLine("Socket() is OK...");

                IPEndPoint ListeningEndPoint = new IPEndPoint(IPAddress.Any, Port);

                Console.WriteLine("IPEndPoint() is OK...");

                ListeningSocket.Bind(ListeningEndPoint);

                Console.WriteLine("Bind() is OK...");

                ListeningSocket.Listen(5);

                Console.WriteLine("Listen() is OK...");

 

                Console.WriteLine("Awaiting a TCP connection on IP: "

                    + ListeningEndPoint.Address.ToString()

                    + " Port: "

                    + ListeningEndPoint.Port.ToString()

                    + "...");

 

                int ConnectionCount = 0;

 

                while (true)

                {

                    ServerSocket = ListeningSocket.Accept();

                    ConnectionCount++;

                    Console.WriteLine("Connection #" + ConnectionCount.ToString() + " is established and awaiting data...");

                    NetworkStreamHandler NSH = new NetworkStreamHandler(ServerSocket, ConnectionCount);

                }

            }

            catch (SocketException e)

            {

                Console.WriteLine("Failure to create Sockets: " + e.Message);

                return;

            }

            finally

            {

                // Close the listening socket - we do not plan to handle any additional connections.

                ListeningSocket.Close();

            }

        }

 

        public class NetworkStreamHandler

        {

            private byte[] Buffer = new byte[4096];

            private AsyncCallback AsyncReceiveCallback = new AsyncCallback(ProcessReceiveResults);

            // Let's create a network stream to communicate over the connected Socket.

            private NetworkStream ServerNetworkStream = null;

            private int ConnectionNumber = 0;

 

            public NetworkStreamHandler(Socket ServerSocket, int ConnectionID)

            {

                ConnectionNumber = ConnectionID;

                try

                {

                    // Setup a network stream on the server Socket

                    ServerNetworkStream = new NetworkStream(ServerSocket, true);

                    Console.WriteLine("NetworkStream() is OK...");

                    ServerNetworkStream.BeginRead(Buffer, 0, Buffer.Length, AsyncReceiveCallback, this);

                    Console.WriteLine("BeginRead() is OK...");

                }

                catch (Exception e)

                {

                    Console.WriteLine(e.Message);

                }

            }

 

            static void ProcessReceiveResults(IAsyncResult ar)

            {

                NetworkStreamHandler NSH = (NetworkStreamHandler)ar.AsyncState;

 

                try

                {

                    int BytesRead = 0;

                    BytesRead = NSH.ServerNetworkStream.EndRead(ar);

                    Console.WriteLine("Connection #" + NSH.ConnectionNumber.ToString() + " received " + BytesRead.ToString() + " byte(s).");

 

                    if (BytesRead == 0)

                    {

                        Console.WriteLine("Connection #" + NSH.ConnectionNumber.ToString() + " is closing.");

                        NSH.ServerNetworkStream.Close();

                        return;

                    }

 

                    NSH.ServerNetworkStream.BeginRead(NSH.Buffer, 0, NSH.Buffer.Length, NSH.AsyncReceiveCallback, NSH);

                }

                catch (Exception e)

                {

                    Console.WriteLine("Failed to read from a network stream with error: " + e.Message);

                    NSH.ServerNetworkStream.Close();

                }

            }

        }

    }

}

 

Build and run the project. The following is a sample output which shows the receiver is waiting connections.

 

C# Asynchronous I/O Program Example - a sample output in action, waiting for connection  

 

To verify the functionalities, let run two clients. The clients are the previously created programs. NetworkStreamSampleVBSender.exe and NetworkStreamSampleCSSender.exe.

Firstly, run the receiver, AsyncNetworkIOCS.exe. Then, run the senders. The following is a sample outputs for two senders and the receiver.

In this case we test on the local host. You may want to test these sender/receiver programs on different hosts which mean the receiver and senders are on different hosts.

 

C# Asynchronous I/O Program Example - a sample output that shows communication of several clients and server/receiver

 

 

 


 

< Asynchronous & C++ I/O Program Example | Main | VB .NET Asynchronous I/O & C++ Thread and Network I/O Examples >