|
VB .NET Asynchronous I/O Program Example
Create a new class library project and you can use the solution and project name as shown in the following snapshots.
Add the following codes. |
Imports System Imports System.Net Imports System.Net.Sockets
' 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.
Public Class Class1 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 a TCP connection 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 = ConnectionCount + 1 Console.WriteLine() Console.WriteLine("Connection #" + ConnectionCount.ToString() + " is established and awaiting data...") Dim NSH As NetworkStreamHandler = New NetworkStreamHandler(ServerSocket, ConnectionCount) End While Catch e As SocketException Console.WriteLine("Failure to create Sockets: " + e.Message) Exit Sub Finally ' Close the listening socket - we do not plan to handle any additional connections. ListeningSocket.Close() End Try End Sub
Public Class NetworkStreamHandler Private Buffer(4096) As Byte Private AsyncReceiveCallback As AsyncCallback = New AsyncCallback(AddressOf ProcessReceiveResults)
' 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...") ServerNetworkStream.BeginRead(Buffer, 0, Buffer.GetUpperBound(0) - 1, AsyncReceiveCallback, Me) Console.WriteLine("BeginRead() is OK...") Catch e As Exception Console.WriteLine(e.Message) End Try End Sub
Shared Sub ProcessReceiveResults(ByVal ar As IAsyncResult) Dim NSH As NetworkStreamHandler = ar.AsyncState
Try Dim BytesRead As Integer = 0 BytesRead = NSH.ServerNetworkStream.EndRead(ar) Console.WriteLine("Connection #" + NSH.ConnectionNumber.ToString() _ + " received " + BytesRead.ToString() + " byte(s).")
If (BytesRead = 0) Then Console.WriteLine("Connection #" + NSH.ConnectionNumber.ToString() + " is closing.") NSH.ServerNetworkStream.Close() Exit Sub End If NSH.ServerNetworkStream.BeginRead(NSH.Buffer, 0, NSH.Buffer.GetUpperBound(0) - 1, NSH.AsyncReceiveCallback, NSH)
Catch e As Exception Console.WriteLine("Failed to read from a network stream with error: " + e.Message) NSH.ServerNetworkStream.Close() End Try End Sub End Class End Class |
Build and run the project. The following is a sample output.
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.
Create a new CLR console application project and you might want to use ThreadNetworkIOCP for the project and solution names as shown below.
Add the following code.
// ThreadNetworkIOCP.cpp : main project file. // <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>
#include "stdafx.h"
using namespace System; using namespace System::Net; using namespace System::Net::Sockets; using namespace System::Threading;
public ref class NetworkStreamHandler { // Let's create a network stream to communicate over the connected Socket. static NetworkStream^ ServerNetworkStream = nullptr; static int ConnectionNumber = 0;
public: NetworkStreamHandler(Socket^ ServerSocket, int ConnectionID) { ConnectionNumber = ConnectionID; try { // Setup a network stream on the server Socket ServerNetworkStream = gcnew NetworkStream(ServerSocket, true); Console::WriteLine("NetworkStream() is OK..."); } catch (Exception^ e) { Console::WriteLine("Network stream failed with error: " + e->Message); }
try { ThreadStart^ NetworkThreadMethod = gcnew ThreadStart(this, &NetworkStreamHandler::ThreadHandlerMethod); Console::WriteLine("ThreadStart() is OK..."); Thread^ NetworkThread = gcnew 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(); } }
void ThreadHandlerMethod() { try { array< Byte >^ Buffer = gcnew array< 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(); } } };
// <summary> // The main entry point for the application. // </summary> [STAThread] int main(array<System::String ^> ^args) { // Default port number, with localhost as listener int Port = 5150;
Environment::GetCommandLineArgs();
// Parse command line arguments if any if(args->Length != 2) { Console::WriteLine("Usage: {0} [/port <port number>]", Environment::CommandLine); return 0; }
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 = Convert::ToInt32(args[++i]->ToString()); } } // This just redundant... catch (IndexOutOfRangeException^) { Console::WriteLine("Usage: {0} [/port <port number>]", Environment::CommandLine); return 0; } }
Socket^ ServerSocket = nullptr; Socket^ ListeningSocket = nullptr;
try { // Setup a listening Socket to await a connection from a peer socket. ListeningSocket = gcnew Socket(AddressFamily::InterNetwork, SocketType::Stream, ProtocolType::IP); Console::WriteLine("Socket() is OK..."); // Listening on all interface... IPEndPoint^ ListeningEndPoint = gcnew 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, I\'m listening for connection...");
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 = gcnew 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. Console::WriteLine("Closing a listening socket..."); ListeningSocket->Close(); } return 0; } |
Build and run the project. Unblock the connection if any.
![]() |
|
The following is the output sample that using port number 8181 and listening to any interfaces of the localhost. The receiver is waiting for connection.
Next, let test sending some messages from three clients to the receiver. We use the previously created sender program examples: networkstreamsamplecpsender (C++), networkstreamsamplevbsender (VB .NET) and networkstreamsamplecssender (C#).
The following is the output sample when the communication was completed.