< C# Asynchronous Class Example | Main | C# Asynchronous Server Program Example >


 

Chapter 9 Part 3:

Server or Listening Sockets Programming

 

 

What do we have in this chapter 9 Part 3?

  1. A Simple VB .NET Asynchronous Class Example

 

A Simple VB .NET Asynchronous Class Example

 

In this example, we will create a shared asynchronous packet class that will be used by the VB .NET server and client programs that will be created later. Create a new class library project and you might want to use AsyncPacketClass as the project and AsyncPacketClassVB as the solution names as shown in the following Figure.

 

A Simple VB .NET Asynchronous Class Example - creating a new class library project in VS 2008 IDE

 

Rename the source file to AsyncPacket to reflect the application that we will build.

 

A Simple VB .NET Asynchronous Class Example - renaming the source file

 

Add the following Imports directives.

 

Imports System

Imports System.Net

Imports System.Net.Sockets

Imports System.Collections

Imports System.Threading

 

In the class add an IoPacketType enum.

 

    'Indicates the type of asynchronous operation.

    Public Enum IoPacketType   

        Accept

        Connect

        Send

        SendTo

        Receive

        ReceiveFrom

    End Enum

 

A Simple VB .NET Asynchronous Class Example - adding the Enum code

 

Next, add the IoPacket class.

 

    ' Describes an IO asynchronous IO request. This class contains the delegate which

    ' is fired when the specified operation completes. It also allocates the data

    ' buffer used by a send or receive operation.   

    Public Class IoPacket

        Public ioType As IoPacketType

        Public connObject As SocketConnection

        Public ioCallback As AsyncCallback

        Public dataBuffer() As Byte

 

        Public IoPacketDefaultBufferSize As Integer = 4096

 

        ' Initialize member variables and allocate the data buffer if this IO packet

        ' describes an asynchronous send or receive operation.       

        ' <param name="connObj">Connection object to which this IO packet belongs to</param>

        ' <param name="packetType">Operation type being created</param>

        Public Sub New(ByVal connObj As SocketConnection, ByVal packetType As IoPacketType)

            ioType = packetType

            connObject = connObj

            ioCallback = New AsyncCallback(AddressOf IoCompleteCallback)

 

            ' If this packet describes a send or receive operation create the

            ' data buffer.

            If (packetType <> IoPacketType.Accept) Then

                ReDim dataBuffer(IoPacketDefaultBufferSize)

            End If

        End Sub

 

        ' Posts an asynchronous connect operation on the underlying TCP socket.       

        ' <param name="serverEndPoint"></param>

        Public Sub PostConnect(ByVal serverEndPoint As IPEndPoint)

            Try

                connObject.tcpSocket.BeginConnect(serverEndPoint, ioCallback, Me)

                connObject.IncrementOutstanding(ioType)

                'Console.WriteLine("Posting a BeginConnect...")

            Catch err As SocketException

                Console.WriteLine("IoPacket.PostConnect: {0}", err.Message)

                Throw

            End Try

        End Sub

 

        ' Posts an asynchronous accept operation on the underlying TCP socket.

        Public Sub PostAccept()

            Try

                ' Post the async accept and increment the accept count

                connObject.tcpSocket.BeginAccept(ioCallback, Me)

                connObject.IncrementOutstanding(ioType)

                'Console.WriteLine("Posting a BeginAccept...")

            Catch err As SocketException

                Console.WriteLine("IoPacket.PostAccept: {0}", err.Message)

                Throw

            End Try

        End Sub

 

        ' Posts an asynchronous receive operation on the underlying TCP socket.

        Public Sub PostReceive()

            Try

                ' Post the async receive and increment the accept count

                connObject.tcpSocket.BeginReceive( _

                    dataBuffer, _

                    0, _

                    dataBuffer.Length, _

                    SocketFlags.None, _

                    ioCallback, _

                    Me _

                    )

                connObject.IncrementOutstanding(ioType)

                'Console.WriteLine("Posting a BeginReceive...")

            Catch err As SocketException

                Console.WriteLine("IoPacket.BeginReceive: {0}", err.Message)

                Throw

            End Try

        End Sub

 

        ' Posts an asynchronous send operation on the underlying TCP socket.

        Public Sub PostSend()

            Try

                ' Post an async send and increment the send count

                connObject.tcpSocket.BeginSend( _

                    dataBuffer, _

                    0, _

                    dataBuffer.Length, _

                    SocketFlags.None, _

                    ioCallback, _

                    Me _

                    )

                connObject.IncrementOutstanding(ioType)

                'Console.WriteLine("Posting a BeginSend...")

            Catch err As SocketException

                Console.WriteLine("IoPacket.BeginSend: {0}", err.Message)

                Throw

            End Try

        End Sub

        ' This is the asynchronous delegate that is called when an operation on the posted

        ' IO object completes. This method simply calls the owning objects HandleIo method.

        ' Only object derived from the SocketConnection class can use this IoPacket class

        ' for describing async IO operations.

        ' <param name="ar">Asynchronous context information</param>

        Sub IoCompleteCallback(ByVal ar As IAsyncResult)

            Dim ioOperation As IoPacket = CType(ar.AsyncState, IoPacket)

 

            ioOperation.connObject.DecrementOutstanding(ioOperation.ioType)

            ioOperation.connObject.HandleIo(ioOperation, ar)

        End Sub

    End Class

 

Then, add the SocketConnection class.

 

 

 

 

    ' Base class from which the TcpServer and ClientConnection objects are derived

    ' from.   

    Public MustInherit Class SocketConnection

        Public tcpSocket As Socket

        Public tcpAddress As IPEndPoint

        Protected receiveOutstanding As Integer

        Protected receiveFromOutstanding As Integer

        Protected sendOutstanding As Integer

        Protected sendToOutstanding As Integer

        Protected connectOutstanding As Integer

        Protected acceptOutstanding As Integer

        Protected sendByteCount As Integer

        Protected receiveByteCount As Integer

 

        ' Simple constructor to initialize counters to zero.       

        Public Sub New()

            receiveOutstanding = 0

            receiveFromOutstanding = 0

            sendOutstanding = 0

            sendToOutstanding = 0

            connectOutstanding = 0

            acceptOutstanding = 0

            sendByteCount = 0

            receiveByteCount = 0

        End Sub

 

        ' Returns the total bytes sent on the socket.       

        Public ReadOnly Property TotalSendBytes() As Integer

            Get

                Return sendByteCount

            End Get

        End Property

 

        ' Returns the total bytes received on the socket.

        Public ReadOnly Property TotalReceiveBytes() As Integer

            Get

                Return receiveByteCount

            End Get

        End Property

 

        ' This method handles the IO operation that completed.       

        ' <param name="io">Object describing the IO operation that completed</param>

        ' <param name="ar">Asynchronous context information</param>

        Public MustOverride Sub HandleIo(ByVal io As IoPacket, ByVal ar As IAsyncResult)

 

        ' Removes the indicated IO packet from any lists or queues the packet may be in

        ' <param name="io">IO object to remove from any lists</param>

        Public MustOverride Sub RemoveIo(ByVal io As IoPacket)

 

        ' Increments the count for the outstanding operation type. This is implemented such

        ' that the IoPacket post routines can make a call to increment the count such that

        ' the caller of each post routine doesn't have to make the increment call.       

        ' <param name="ioType">Operation type to increment count for</param>

        Public Sub IncrementOutstanding(ByVal ioType As IoPacketType)

            Select Case ioType

                Case IoPacketType.Connect

                    Interlocked.Increment(connectOutstanding)

                Case IoPacketType.Accept

                    Interlocked.Increment(acceptOutstanding)

                Case IoPacketType.Receive

                    Interlocked.Increment(receiveOutstanding)

                Case IoPacketType.ReceiveFrom

                    Interlocked.Increment(receiveFromOutstanding)

                Case IoPacketType.Send

                    Interlocked.Increment(sendOutstanding)

                Case IoPacketType.SendTo

                    Interlocked.Increment(sendToOutstanding)

                Case Else

            End Select

        End Sub

 

        ' Decrements the count for the outstanding operation type. This is implemented such

        ' that the IoPacket post routines can make a call to decrement the count such that

        ' the caller of each post routine doesn't have to make the decrement call.       

        ' <param name="ioType">Operation type to decrement count for</param>

        Public Sub DecrementOutstanding(ByVal ioType As IoPacketType)

            Select Case ioType

                Case IoPacketType.Connect

                    Interlocked.Decrement(connectOutstanding)

                Case IoPacketType.Accept

                    Interlocked.Decrement(acceptOutstanding)

                Case IoPacketType.Receive

                    Interlocked.Decrement(receiveOutstanding)

                Case IoPacketType.ReceiveFrom

                    Interlocked.Decrement(receiveFromOutstanding)

                Case IoPacketType.Send

                    Interlocked.Decrement(sendOutstanding)

                Case IoPacketType.SendTo

                    Interlocked.Decrement(sendToOutstanding)

                Case Else

            End Select

        End Sub

    End Class

 

Add the ClientConnection class.

 

 

    ' This class identifies a client connection. It keeps track of all outstanding

    ' async send and receive operations and handles completed IO operations.

    Public Class ClientConnection

        Inherits SocketConnection

        Private ownerList As ArrayList

        Private ownerEvent As ManualResetEvent

        Private sendList As ArrayList

        Private recvList As ArrayList

        Private sendCountLeft As Integer

        Private connectPacket As IoPacket

 

        ' This is the constructor for the client which takes only the client socket

        ' object. It creates the lists of outstanding send and receive operations

        ' and posts the initial BeginReceive.

        ' <param name="tcpClient">Socket object representing the client connection</param>

        ' <param name="serverObject">Reference to the server object that owns this client connection</param>

        Public Sub New(ByVal serverEndPoint As IPEndPoint, ByVal clientList As ArrayList, ByVal clientEmpty As ManualResetEvent)

            MyBase.New()

            ownerList = clientList

            ownerEvent = clientEmpty

            sendList = New ArrayList

            recvList = New ArrayList

            sendCountLeft = 15

 

            tcpSocket = New Socket( _

                serverEndPoint.AddressFamily, _

                SocketType.Stream, _

                ProtocolType.Tcp _

                )

 

            connectPacket = New IoPacket(Me, IoPacketType.Connect)

 

            Try

                connectPacket.PostConnect(serverEndPoint)

            Catch err As Exception

                Console.WriteLine("ClientConnection: PostConnect failed: {0}", err.Message)

            End Try

        End Sub

 

        ' This overrided routine handles all asynchronous IO that completes on the ClientConnection

        ' object. Since the client only sends and receives only the Send and Receive commands are

        ' handled. The client connection first receives a request from the client until the client

        ' shuts down the send path. At this point the client connection will receive zero bytes

        ' indicating the client is done sending. This is followed by the client sending a response

        ' to the client. Once the requested number of send operations are performed to the client

        ' the client socket is closed and resources are freed (by closing the socket handle and

        ' indicating to the owning TcpServer to remove the ClientConnection object from its list of connections).

        ' <param name="io">IO packet object that describes the completed operation</param>

        ' <param name="ar">Asynchronous context information for the completed operation</param>

        Public Overrides Sub HandleIo(ByVal io As IoPacket, ByVal ar As System.IAsyncResult)

            Dim rc As Integer

 

            Select Case io.ioType

                Case IoPacketType.Connect

                    ' Connect operation completed                   

                    Try

                        tcpSocket.EndConnect(ar)

 

                        ' Add the IoPacket to the send list

                        sendList.Add(io)

                        ' Make it a send operation and post a send operation

                        io.ioType = IoPacketType.Send

                        io.PostSend()

                    Catch err As Exception

                        Console.WriteLine("Socket connect failed: {0}", err.Message)

                        tcpSocket.Close()

                        ownerList.Remove(Me)

                        ownerEvent.Set()

                    End Try

 

                Case IoPacketType.Send

                    ' An async send operation completed, first decrement the number of sends left

                    Interlocked.Decrement(sendCountLeft)

 

                    Try

                        ' Get the results from the send

                        rc = tcpSocket.EndSend(ar)

                        ' Update counters

                        sendByteCount += rc

                        'Console.WriteLine("Client wrote {0} bytes", rc)

 

                        ' Check to see if we're done sending, if so close the socket and clean

                        ' up the IoPacket used.

                        If (sendCountLeft = 0) Then

                            'Console.WriteLine("Shutting down connection")

                            tcpSocket.Shutdown(SocketShutdown.Send)

                            RemoveIo(io)

                            io.ioType = IoPacketType.Receive

                            recvList.Add(io)

                            io.PostReceive()

                        Else

                            ' If there are still sends left, post another async send operation

                            io.PostSend()

                        End If

 

                    Catch err As Exception

                        Console.WriteLine("ClientConnection.HandleIo: Send op failed: {0}", err.Message)

                        tcpSocket.Close()

                        ownerList.Remove(Me)

                        ownerEvent.Set()

                    End Try

 

                Case IoPacketType.Receive

                    ' An async receive operation completed

                    Try

                        ' Get the results from the operation

                        rc = tcpSocket.EndReceive(ar)

                        ' Update the byte counters

                        receiveByteCount += rc

 

                        ' Console.WriteLine("Client read {0} bytes", rc)

 

                        ' If zero bytes were returned, the client has shutdown its send side. This

                        ' side then initiates sending data back to the client.

                        If (rc = 0) Then

                            'Console.WriteLine("Client connection shutdown...")

                            ' Once the entire request is received start the response

                            RemoveIo(io)

                            tcpSocket.Close()

                            ownerList.Remove(Me)

                            ownerEvent.Set()

                        Else

                            ' Client hasn't finished sending data so post another async receive

                            io.PostReceive()

                        End If

                    Catch err As Exception

                        ' Clean up the client connection if a receive fails

                        Console.WriteLine("ClientConnection.HandleIo: Receive op failed: {0}", err.Message)

                        tcpSocket.Close()

                        ownerList.Remove(Me)

                        ownerEvent.Set()

                    End Try

                Case Else

                    ' Should never be here

                    Console.WriteLine("ClientConnection.HandleIo: Accept indication received ?!?!")

            End Select

        End Sub

 

        ' Removes the given IoPacket from the appropriate ArrayList depending on the operation

        ' type.

        Public Overrides Sub RemoveIo(ByVal io As IoPacket)

            Select Case io.ioType

                Case IoPacketType.Receive

                    recvList.Remove(io)

                Case IoPacketType.Send

                    sendList.Remove(io)

                Case Else

            End Select

            io = Nothing

        End Sub

    End Class

 

 

Add the AcceptConnection class.

 

    ' This class identifies a client connection. It keeps track of all outstanding

    ' async send and receive operations and handles completed IO operations.

    Public Class AcceptConnection

        Inherits SocketConnection

 

        Private sendList As ArrayList

        Private recvList As ArrayList

        Private tcpParent As TcpServer

        Private sendCountLeft As Integer

 

        ' This is the constructor for the client which takes only the client socket

        ' object. It creates the lists of outstanding send and receive operations

        ' and posts the initial BeginReceive.       

        ' <param name="tcpClient">Socket object representing the client connection</param>

        ' <param name="serverObject">Reference to the server object that owns this client connection</param>

        Public Sub New(ByVal tcpClient As Socket, ByVal serverObject As TcpServer)

            MyBase.New()

            tcpSocket = tcpClient

            sendList = New ArrayList

            recvList = New ArrayList

            tcpParent = serverObject

 

            sendCountLeft = 15

            Console.WriteLine("Client connection from: {0}", tcpSocket.RemoteEndPoint.ToString())

 

            ' Post the initial BeginReceive on the client socket           

            Dim recvPacket As IoPacket = New IoPacket(Me, IoPacketType.Receive)

 

            recvList.Add(recvPacket)

 

            Try

                recvPacket.PostReceive()

            Catch err As Exception

                Console.WriteLine("AcceptConnection.ClientConnection: PostReceive failed: {0}", err.Message)

            End Try

        End Sub

 

        ' This overrided routine handles all asynchronous IO that completes on the ClientConnection

        ' object. Since the client only sends and receives only the Send and Receive commands are

        ' handled. The client connection first receives a request from the client until the client

        ' shuts down the send path. At this point the client connection will receive zero bytes

        ' indicating the client is done sending. This is followed by the client sending a response

        ' to the client. Once the requested number of send operations are performed to the client

        ' the client socket is closed and resources are freed (by closing the socket handle and

        ' indicating to the owning TcpServer to remove the ClientConnection object from its list

        ' of connections).       

        ' <param name="io">IO packet object that describes the completed operation</param>

        ' <param name="ar">Asynchronous context information for the completed operation</param>

        Public Overrides Sub HandleIo(ByVal io As IoPacket, ByVal ar As System.IAsyncResult)

            Dim rc As Integer

 

            Select Case io.ioType

                Case IoPacketType.Send

                    ' An async send operation completed, first decrement the number of sends left

                    Interlocked.Decrement(sendCountLeft)

 

                    Try

                        ' Get the results from the send

                        rc = tcpSocket.EndSend(ar)

                        ' Update counters

                        sendByteCount += rc

                        tcpParent.IncrementByteCount(rc, 0)

 

                        ' Console.WriteLine("Client wrote {0} bytes", rc)

 

                        ' Check to see if we're done sending, if so close the socket and clean

                        '  up the IoPacket used.

                        If (sendCountLeft = 0) Then

                            tcpSocket.Shutdown(SocketShutdown.Send)

                            tcpSocket.Close()

                            RemoveIo(io)

                            io = Nothing

                            tcpSocket = Nothing

 

                            ' Console.WriteLine("Connection finished...")                       

                        Else

                            ' If there are still sends left, post another async send operation

                            io.PostSend()

                        End If

                    Catch err As Exception

                        Console.WriteLine("AcceptConnection.HandleIo: Send op failed: {0}", err.Message)

                        tcpSocket.Close()

                        tcpSocket = Nothing

                    Finally

                        ' Check to see if the client connection is done, if so indicate to the TcpServer

                        '     parent to remove the client from its list.

 

                        ' Console.WriteLine("sendCountLeft = {0} | sendOutstanding = {1} | recvOutstanding = {2}", _

                        '    sendCountLeft, _

                        '    sendOutstanding, _

                        '    MyBase.receiveOutstanding _

                        '    )

 

                        If (IsNothing(tcpSocket) And (sendCountLeft = 0) And _

                            (sendOutstanding = 0) And (receiveOutstanding = 0) _

                            ) Then

                            tcpParent.RemoveClient(Me)

                        End If

                    End Try

 

                Case IoPacketType.Receive

                    ' An async receive operation completed                   

                    Try

                        ' Get the results from the operation

                        rc = tcpSocket.EndReceive(ar)

                        ' Update the byte counters

                        receiveByteCount += rc

                        tcpParent.IncrementByteCount(0, rc)

 

                        ' Console.WriteLine("Client read {0} bytes", rc)

 

                        ' If zero bytes were returned, the client has shutdown its send side. This

                        ' side then initiates sending data back to the client.

                        If (rc = 0) Then

                            ' Console.WriteLine("Client connection shutdown...")

                            ' Once the entire request is received start the response

                            RemoveIo(io)

                            ' Switch the packet type to sending

                            io.ioType = IoPacketType.Send

                            sendList.Add(io)

                            ' Post a send operation to the client

                            io.PostSend()

                        Else

                            ' Client hasn't finished sending data so post another async receive

                            io.PostReceive()

                        End If

                    Catch err As Exception

                        ' Clean up the client connection if a receive fails

                        Console.WriteLine("ClientConnection.HandleIo: Receive op failed: {0}", err.Message)

                        tcpSocket.Close()

                        tcpSocket = Nothing

                        tcpParent.RemoveClient(Me)

                    End Try

                Case Else

                    ' Should never be here                   

                    Console.WriteLine("AcceptConnection.HandleIo: Accept indication received ?!?!")

            End Select

        End Sub

 

        ' Removes the given IoPacket from the appropriate ArrayList depending on the operation

        ' type.       

        ' <param name="io">IO object to remove from any lists</param>

        Public Overrides Sub RemoveIo(ByVal io As IoPacket)

            Select Case (io.ioType)

                Case IoPacketType.Receive

                    recvList.Remove(io)

                Case IoPacketType.Send

                    sendList.Remove(io)

                Case Else

            End Select

            io = Nothing

        End Sub

    End Class

 

Finally, add the TcpServer class.

 

    ' This class encapsulates functionality for the TCP server object. This

    ' class keeps track of all clients accepted on the listening socket

    ' as well as the outstanding asynchronous accept operations. The class

    ' keeps track the send and receive byte counters and client counts.   

    Public Class TcpServer

        Inherits SocketConnection

        Private clientList As ArrayList

        Private clientSyncList As ArrayList

        Private acceptList As ArrayList

        Private serverShutdown As Integer

        Public serverDone As ManualResetEvent

        Public totalClientCount As Integer

        Public currentClientCount As Integer

 

        ' Simple constructor for the TcpServer class. This initializes the counters

        ' and creates the listening TCP socket.       

        ' <param name="listenEndPoint">Endpoint to create the listening socket on</param>

        ' <param name="asyncListenLimit">Maximum number of async accepts outstanding</param>

        Public Sub New(ByVal listenEndPoint As IPEndPoint, ByVal asyncListenLimit As Integer)

            MyBase.New()

 

            Dim optval As Integer = 1

 

            ' Initialize some member variables

            serverShutdown = 0

            totalClientCount = 0

            currentClientCount = 0

            serverDone = New ManualResetEvent(False)

 

            ' Create the listening socket

            tcpSocket = New Socket( _

                listenEndPoint.AddressFamily, _

                SocketType.Stream, _

                ProtocolType.Tcp _

                )

 

            ' Set exclusive use so that the port we bind to cannot be stolen by anyone else

            tcpSocket.SetSocketOption( _

                SocketOptionLevel.Socket, _

                SocketOptionName.ExclusiveAddressUse, _

                optval _

                )

 

            ' Bind the socket to the specified address and port

            tcpSocket.Bind(listenEndPoint)

            ' Set the socket to listening

            tcpSocket.Listen(Integer.MaxValue)

            ' Indicate what address/port socket is listening on

            Console.WriteLine("Listening on {0}", listenEndPoint.ToString())

            ' Create list for outstanding client connections

            clientList = New ArrayList

            clientSyncList = ArrayList.Synchronized(clientList)

            ' Create list for outstanding BeginAccept operations

            acceptList = New ArrayList

            ' Post the initial BeginAccepts on the listening socket

            Dim i As Integer

            For i = 0 To asyncListenLimit - 1

                Dim acceptPacket As IoPacket = New IoPacket(Me, IoPacketType.Accept)

 

                acceptList.Add(acceptPacket)

                Try

                    acceptPacket.PostAccept()

                Catch err As Exception

                    Console.WriteLine("TcpServer.TcpServer: PostAccept failed: {0}", err.Message)

                End Try

            Next

        End Sub

 

        ' This method removes an accepted client object (AcceptConnection) from the

        ' list of accepted connections. It decrements the current client count.       

        ' <param name="clientObject">Accepted client object to remove</param>

        Public Sub RemoveClient(ByVal clientObject As AcceptConnection)

            clientSyncList.Remove(clientObject)

            clientObject = Nothing

            Interlocked.Decrement(currentClientCount)

        End Sub

 

        ' This method marks the TcpServer as shutting down. This flag is set before all the

        ' listening sockets are closed.

        Public Sub Shutdown()

            Interlocked.Increment(serverShutdown)

        End Sub

 

        ' This routine handles all IO completion events initiated by the TcpServer

        ' listening socket which will consist of BeginAccept events. Before accessing

        ' the socket, a check is made to make sure the server is not shutting down

        ' in which case the listening socket have already been closed.

        ' <param name="io">IO packet describing the operation that completed</param>

        ' <param name="ar">Asynchronous context information</param>

        Public Overrides Sub HandleIo(ByVal io As IoPacket, ByVal ar As System.IAsyncResult)

            Select Case io.ioType

                Case IoPacketType.Accept

                    'Console.WriteLine("TcpServer.HandleIo: Accept completed: outstanding {0}", acceptOutstanding )

 

                    If (serverShutdown <> 0) Then

                        io.connObject.RemoveIo(io)

                        Exit Sub

                    End If

                    Try

                        Dim clientSocket As Socket

                        Dim clientConn As AcceptConnection

 

                        Try

                            ' Handle the accept that completed

                            clientSocket = tcpSocket.EndAccept(ar)

                            clientConn = New AcceptConnection(clientSocket, Me)

                            clientSyncList.Add(clientConn)

                            ' Update the counters

                            Interlocked.Increment(totalClientCount)

                            Interlocked.Increment(currentClientCount)

                        Catch

                            Console.WriteLine("Accept: Client aborted connection most likely...")

                        End Try

 

                        ' Repost the accept

                        io.PostAccept()

 

                    Catch err As Exception

                        Console.WriteLine("TcpServer.HandleIo: Unknown error: {0}", err.Message)

                        acceptList.Remove(io)

                        io = Nothing

                    End Try

                Case Else

            End Select

        End Sub

 

        ' This method removes the IoPacket from the appropriate list.

        ' <param name="io">The IoPacket to remove from the correct list</param>

        Public Overrides Sub RemoveIo(ByVal io As IoPacket)

            Select Case io.ioType

                Case IoPacketType.Accept

                    acceptList.Remove(io)

                    io = Nothing

                Case Else

            End Select

        End Sub

 

        ' Increments the sent and received byte counts for all client connections established

        ' on this TCP server socket. Each AcceptConnection has a reference to the TcpServer

        ' on which the client connection was accepted -- it then calls this method to

        ' increment the byte counters.

        ' <param name="sendCount">Number of bytes sent to increment counter by</param>

        ' <param name="recvCount">Number of bytes received to increment counter by</param>

        Public Sub IncrementByteCount(ByVal sendCount As Integer, ByVal recvCount As Integer)

            MyBase.sendByteCount += sendCount

            MyBase.receiveByteCount += recvCount

        End Sub

    End Class

 

Build the project and make sure there is no error that can be seen in the Output window.

 

A Simple VB .NET Asynchronous Class Example - building the project using the IDE Build Solution menu

 

The generated DLL that we will refer later in other project is shown below.

 

A Simple VB .NET Asynchronous Class Example - the generated DLL file that is ready to be used as shared DLL

 

The namespace that will be used as reference to the class created is AsyncPacketClass as can be seen in the Property page.

 

A Simple VB .NET Asynchronous Class Example - invoking the project's property page from Properties context menu

 

 

A Simple VB .NET Asynchronous Class Example - the project's property page checking the root namespace

 


< C# Asynchronous Class Example | Main | C# Asynchronous Server Program Example >