|
VB .NET Asynchronous Server Program Example
Create a new class library project and you might want to use the solution name, AsyncTcpServerVB and project name, AsyncTcpServer as shown in the following Figure.
|
Rename the source file to AsyncServer to reflect the application we are going to develop.
Add the following Imports directives.
Imports System Imports System.Net Imports System.Net.Sockets Imports System.Collections Imports System.Threading Imports AsyncPacketClass.AsyncPacket |
Next, add the reference to the AsyncPacketClass. Select project folder > Right click mouse > Select Add Reference context menu.
Browse the AsyncPacketClass project folder.
Browse the DLL file, select the file and click OK.
To make sure the reference to the AsyncPacketClass class is functioning, you can build this project. There should be no error in the Output window. You can also test AsyncPacketClass Imports directive intellisense as shown in the following Figure. After placing the dot (.), any method available in the class will be displayed.
Add the following usage() and the Main() sub routine codes, encapsulated in the AsyncServer class.
' Displays a simple usage information Shared Sub usage() Console.WriteLine("Executable_file_name [-a count] [-l address] [-p port]") Console.WriteLine("Available options:") Console.WriteLine(" -a count Number of simultaneous asynch Accepts (BeginAccept) allowed") Console.WriteLine(" -l address Local address to create a TCP server on (can be specified multiple times") Console.WriteLine(" -p port Local port number each server listens on") Console.WriteLine() End Sub
' This is the main program that parses the command line parameters and sets up each TCP ' listening socket by creating a TcpServer object to handle client connections to each ' listening endpoint. The TcpServer object creates a AcceptedConection object for each ' established connection which handles IO operations from each client. Shared Sub Main() Dim listenInterfaces As ArrayList = New ArrayList Dim tcpServerList As ArrayList = New ArrayList Dim asyncAcceptLimit As Integer = 10 Dim listenPort As Integer = 5150
' Parse the command line Dim appArguments As String() = Environment.GetCommandLineArgs() Dim i As Integer
usage()
For i = 1 To appArguments.GetUpperBound(0) Try Dim CurArg() As Char = appArguments(i).ToCharArray(0, appArguments(i).Length)
If (CurArg(0) = "-") Or (CurArg(0) = "/") Then Select Case Char.ToLower(CurArg(1), System.Globalization.CultureInfo.CurrentCulture) Case "a" ' How many asynchronous accept (BeginAccepts) allowed simultaneously i += 1 asyncAcceptLimit = System.Convert.ToInt32(appArguments(i)) Case "l" ' Local interface(s) to bind to i += 1 listenInterfaces.Add(IPAddress.Parse(appArguments(i))) Case "p" ' Port on which to listen i += 1 listenPort = System.Convert.ToInt32(appArguments(i)) Case Else usage() Exit Sub End Select End If Catch usage() Exit Sub End Try Next
Dim ServerThread As RunServerThread = New RunServerThread Dim t As Thread
ServerThread.asyncAcceptLimit = asyncAcceptLimit ServerThread.listenInterfaces = New ArrayList(listenInterfaces.Count) ServerThread.listenInterfaces.AddRange(listenInterfaces) ServerThread.listenPort = listenPort ServerThread.tcpServerList = New ArrayList(tcpServerList.Count) ServerThread.tcpServerList.AddRange(tcpServerList)
' Create a new thread and define its starting point. Console.WriteLine("Creating a new thread and define its starting point...") t = New Thread(AddressOf ServerThread.DoTheTask) t.Start() End Sub |
Next, add RunServerThread class
Class RunServerThread Public listenInterfaces As ArrayList Public tcpServerList As ArrayList Public asyncAcceptLimit As Integer Public listenPort As Integer
Public Sub DoTheTask() ' Create an array of handles to signal when server sockets are finished Console.WriteLine("Creating an array of handles to signal when server sockets are finished...") Dim serverWaitHandles(listenInterfaces.Count - 1) As WaitHandle Dim i As Integer
For i = 0 To listenInterfaces.Count - 1 serverWaitHandles(i) = New ManualResetEvent(False) Next
' Create a TCP server socket for each local listen address passed to the application Console.WriteLine("Creating a TCP server socket for each local listen address passed to the application...") For i = 0 To listenInterfaces.Count - 1 Dim listenEndPoint As IPEndPoint Dim listenServer As TcpServer
Try listenEndPoint = New IPEndPoint(CType(listenInterfaces(i), IPAddress), listenPort) listenServer = New TcpServer(listenEndPoint, asyncAcceptLimit) serverWaitHandles(i) = listenServer.serverDone tcpServerList.Add(listenServer) Catch err As Exception Console.WriteLine("Error: {0}", err.Message) End Try Next
Try ' Wait until all the TCP server sockets are done Console.WriteLine("Waiting until all the TCP server sockets are done...") While (True) If (ManualResetEvent.WaitAll(serverWaitHandles, 10000, False) = False) Then ' Wait timed out so print some statistics
Console.WriteLine(" Client Count Byte Count") Console.WriteLine(" Server Address Current/Total Sent/Received")
For i = 0 To tcpServerList.Count - 1 Console.WriteLine(" {0} {1} / {2} {3}/{4}", _ (CType(tcpServerList(i), TcpServer)).tcpSocket.LocalEndPoint.ToString().PadRight(20, " "), _ (CType(tcpServerList(i), TcpServer)).currentClientCount.ToString().PadLeft(12, " "), _ (CType(tcpServerList(i), TcpServer)).totalClientCount.ToString().PadRight(12, " "), _ (CType(tcpServerList(i), TcpServer)).TotalSendBytes.ToString().PadLeft(12, " "), _ (CType(tcpServerList(i), TcpServer)).TotalReceiveBytes.ToString().PadRight(12, " ") _ ) Next Else Exit While End If End While
Console.WriteLine("All listen sockets have been signaled...closing listen sockets...")
For i = 0 To listenInterfaces.Count - 1
Dim listenServer As TcpServer = CType(tcpServerList(i), TcpServer)
listenServer.Shutdown() listenServer.tcpSocket.Close() Next Thread.Sleep(10000) Catch err As Exception Console.WriteLine("Error: {0}", err.Message) End Try End Sub End Class |
In order to test this project on the console, change the project type from DLL to EXE type. Select the project folder > Right click mouse > Select Properties context menu.
Change the Application type: to Console Application and the Startup object: to Sub Main.
Build the project.
Run the project.
The following is the sample output.
In this project, we have included a reference to the AsyncPacketClass library. You can see the DLL file has been included in this project’s Debug folder as shown in the following Figure.
![]() |
|
The following shows the sample output of the asynchronous tcp server when run from the command prompt. We will test this server program together with the client program example later.
The following sample output shows the asynchronous tcp server is receiving a connection from a client. The client program example will be created in the next exercise.