|
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.
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.
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.
Create a new class library project.
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.
Build and run the project. The following is a sample output that shows the server is waiting connections.
Unblock if the following alert box displayed. |
|
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.