< VB .NET Asynchronous I/O & C++ Thread and Network I/O Examples | Main | Chap 4: Serialization >

 


 

Chapter 3 Part 10:

Threading and the Asynchronous Pattern

 

 

What do we have in this chapter 3 Part 10?

  1. C# Thread and Network I/O Program Example

  2. VB .NET Thread and Network I/O Program Example

 

 

C# Thread and Network I/O Program Example

 

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

 

C# Thread and Network I/O Program Example - a new console mode application project creation

 

Add the following code.

 

using System;

using System.Net;

using System.Net.Sockets;

using System.Threading;

 

// <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 threads

// where a thread is created for each connection and IO is processed

// synchronously in each thread. The original sample only accepted 1

// connection and processed IO synchronously. Because this application

// processes IO synchronously using 1 thread per connection, 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 ThreadNetworkIO

{

    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 TCP connections on IP: "

                    + ListeningEndPoint.Address.ToString()

                    + " Port: "

                    + ListeningEndPoint.Port.ToString()

                    + "...");

 

                int ConnectionCount = 0;

 

                while (true)

                {

                    ServerSocket = ListeningSocket.Accept();

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

                    ConnectionCount++;

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

                    NetworkStreamHandler NSH = new NetworkStreamHandler(ServerSocket, ConnectionCount);

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

                }

            }

            catch (SocketException e)

            {

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

            }

            finally

            {

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

                ListeningSocket.Close();

            }

        }

 

        public class NetworkStreamHandler

        {

            // 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...");

                }

                catch (Exception e)

                {

                    Console.WriteLine("Network stream failed with error: " + e.Message);

                    return;

                }

 

                try

                {

                    ThreadStart NetworkThreadMethod = new ThreadStart(ThreadHandlerMethod);

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

                    Thread NetworkThread = new Thread(NetworkThreadMethod);

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

                    NetworkThread.Start();

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

                }

                catch (Exception e)

                {

                    Console.WriteLine("The network thread failed with error: " + e.Message);

                    ServerNetworkStream.Close();

                }

            }

 

            private void ThreadHandlerMethod()

            {

                try

                {

                    byte[ ] Buffer = new byte[4096];

                    int BytesRead = 0;

 

                    do

                    {

                        BytesRead = ServerNetworkStream.Read(Buffer, 0, Buffer.Length);

                        Console.WriteLine();

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

                    }

                    while (BytesRead > 0);

                }

                catch (ThreadAbortException e)

                {

                    Console.WriteLine("Caught thread abort exception: " + e.Message);

                }

                catch (Exception e)

                {

                    Console.WriteLine("Thread routine failed with error: " + e.Message);

                }

                finally

                {

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

                    ServerNetworkStream.Close();

                }

            }

        }

    }

}

 

Build and run the project. The following is a sample output that shows the server is waiting connections from clients.

 

C# Thread and Network I/O Program Example - a sample output in action that shows the receiver/server is waiting for connections

 

The following sample output shows two clients connecting to the server. The clients used in this case are previously created sender programs. You may want to run the programs from different hosts because in this case we run all the programs on the local host.

 

C# Thread and Network I/O Program Example - an output sample of the receiver with two clients

 

VB .NET Thread and Network I/O Program Example

 

Create a new class library project.

 

VB .NET Thread and Network I/O Program Example - a new class library project creation

 

Add the following codes.

 

Imports System

Imports System.Net

Imports System.Net.Sockets

Imports System.Threading

 

' 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 threads

' where a thread is created for each connection and IO is processed

' synchronously in each thread. The original sample only accepted 1

' connection and processed IO synchronously. Because this application

' processes IO synchronously using 1 thread per connection, 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.

 

Public Class Class1

    'The main entry point for the application

    Shared Sub Main()

 

        Dim Port As Integer = 5150

 

        ' Parse command line arguments if any

        Dim args As String() = Environment.GetCommandLineArgs()

        Dim i As Integer

 

        For i = 0 To args.Length - 1

            Try

                If (args(i) = "/port") Then

                    ' The port on which the server is listening

                    i = i + 1

                    Port = System.Convert.ToInt32(args(i).ToString())

                End If

            Catch e As System.IndexOutOfRangeException

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

                Exit Sub

            End Try

        Next

 

        Dim ServerSocket As Socket = Nothing

        Dim ListeningSocket As Socket = Nothing

 

        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...")

            Dim ListeningEndPoint As IPEndPoint = 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 TCP connections on IP: " _

             + ListeningEndPoint.Address.ToString() _

             + " Port: " _

             + ListeningEndPoint.Port.ToString() _

             + "...")

 

            Dim ConnectionCount As Integer = 0

 

            While (True)

                ServerSocket = ListeningSocket.Accept()

                Console.WriteLine("Accept() is OK...")

                ConnectionCount += 1

                Console.WriteLine()

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

                Dim NSH As NetworkStreamHandler = New NetworkStreamHandler(ServerSocket, ConnectionCount)

                Console.WriteLine("NetworkStreamHandler() is OK...")

            End While

        Catch e As SocketException

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

        Finally

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

            ListeningSocket.Close()

        End Try

    End Sub

 

    Public Class NetworkStreamHandler

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

        Private ServerNetworkStream As NetworkStream = Nothing

        Private ConnectionNumber As Integer = 0

 

        Public Sub New(ByVal ServerSocket As Socket, ByVal ConnectionID As Integer)

            ConnectionNumber = ConnectionID

 

            Try

                ' Setup a network stream on the server Socket

                ServerNetworkStream = New NetworkStream(ServerSocket, True)

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

            Catch e As Exception

                Console.WriteLine("Network stream failed with error: " + e.Message)

                Exit Sub

            End Try

 

            Try

                Dim NetworkThreadMethod As ThreadStart = New ThreadStart(AddressOf ThreadHandlerMethod)

                Console.WriteLine("ThreadStart() is OK...")

                Dim NetworkThread As Thread = New Thread(NetworkThreadMethod)

                Console.WriteLine("Thread() is OK...")

                NetworkThread.Start()

                Console.WriteLine("Start() is OK...")

            Catch e As Exception

                Console.WriteLine("The network thread failed with error: " + e.Message)

                ServerNetworkStream.Close()

            End Try

        End Sub

 

        Private Sub ThreadHandlerMethod()

            Try

                Dim Buffer(4096) As Byte

                Dim BytesRead As Integer = 0

 

                Do

                    BytesRead = ServerNetworkStream.Read(Buffer, 0, Buffer.GetUpperBound(0))

                    Console.WriteLine("Connection #" + ConnectionNumber.ToString() _

                     + " received " + BytesRead.ToString() + " byte(s).")

                Loop While (BytesRead > 0)

            Catch e As ThreadAbortException

                Console.WriteLine("Caught thread abort exception: " + e.Message)

            Catch e As Exception

                Console.WriteLine("Thread routine failed with error: " + e.Message)

            Finally

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

                ServerNetworkStream.Close()

            End Try

        End Sub

    End Class

End Class

 

Change the Application type: to Console Application and Startup object: to Sub Main.

 

VB .NET Thread and Network I/O Program Example - changing the project type from DLL to EXE and set the startup to Main() subroutine

 

Build and run the project. The following is a sample output that shows the server is waiting connections.

 

VB .NET Thread and Network I/O Program Example - an output sample that shows the receiver is waiting for connections

 

Unblock if the following alert box displayed.

 

 

VB .NET Thread and Network I/O Program Example - unblocking the Windows personal firewall

 

The following sample output shows two clients that have connected to the server. The clients used in this case are previously created sender programs. You may want to run the programs from different hosts because in this case we run all the programs on the local host.

 

VB .NET Thread and Network I/O Program Example - an output sample that shows a receiver with two clients

 

 

 


 

< VB .NET Asynchronous I/O & C++ Thread and Network I/O Examples | Main | Chap 4: Serialization >