What do we have in this chapter 4 Part 9 (Windows Server 2003)?
VB .NET: The Binary Server Socket Project
Rename the Class1 file under the BinServerVB folder to BinServer.
Add the following code to the BinServer.vb file. |
' This is the server side to the socket serialization sample. This sample illustrates ' binary serialization over a socket stream. The server listens for client connections. ' Once a connection is established, the server receives the serialized data and ' deserializes it. ' ' Usage: ' executable_file_name [/protocol IPv4|IPv6] [/port num] ' ' Sample usage: ' executable_file_name /protocol ipv4 /port 5150
Imports System Imports System.Net Imports System.Net.Sockets Imports System.Runtime.Serialization Imports System.Runtime.Serialization.Formatters.Binary Imports BinData.BinData ' Common data structure to send on wire
Class BinServerClass
' Displays simple usage information. Shared Sub usage() Console.WriteLine("executable_file_name [/protocol IPv4|IPv6]") End Sub
' This is the main routine for the serialization socket server. The server ' parses the command line, creates a TCP listening socket over the requested ' protocol (IPv4 or IPv6), accepts a client connection, and retrieves the ' serialized object the client sent. ' ' <param name="args">Command line arguments passed to server</param> Shared Sub Main() Dim Port As Integer = 5150 Dim ListeningSocket As Socket = Nothing Dim ClientSocket As Socket = Nothing Dim LocalEndPoint As IPEndPoint = Nothing Dim NetStream As NetworkStream Dim formatter As IFormatter = New BinaryFormatter Dim data As BinDataClass Dim buffer(5) As Byte ' Use IPv4 as initial value Dim ServerAddressFamily As AddressFamily = AddressFamily.InterNetwork
' Parse the command line Dim args As String() = Environment.GetCommandLineArgs() Dim i As Integer For i = 1 To args.Length - 1 If args(i) = "/protocol" Then Try i = i + 1 If args(i) = "IPv6" Then ServerAddressFamily = AddressFamily.InterNetworkV6 ElseIf args(i) = "IPv4" Then ServerAddressFamily = AddressFamily.InterNetwork Else usage() Exit Sub End If Catch e As System.IndexOutOfRangeException usage() Exit Sub End Try ElseIf args(i) = "/port" Then
Try i = i + 1 Port = Convert.ToInt32(args(i)) Catch e As System.IndexOutOfRangeException usage() Exit Sub End Try Else usage() Exit Sub End If Next
' Create the appropriate listening socket If ServerAddressFamily = AddressFamily.InterNetwork Then ListeningSocket = New Socket( _ AddressFamily.InterNetwork, _ SocketType.Stream, _ ProtocolType.Tcp _ ) LocalEndPoint = New IPEndPoint(IPAddress.Any, Port) Console.WriteLine("IPv4 socket() is OK...")
Else ListeningSocket = New Socket( _ AddressFamily.InterNetworkV6, _ SocketType.Stream, _ ProtocolType.Tcp _ )
' LocalEndPoint = new IPEndPoint( IPAddress.IPv6Any, Port ) LocalEndPoint = New IPEndPoint(IPAddress.IPv6Any, Port) Console.WriteLine("IPv6 socket() is OK...") End If
' Bind the socket to the interface we will accept connections one ListeningSocket.Bind(LocalEndPoint) Console.WriteLine("Bind() is OK...")
' Set the listen backlog to five ListeningSocket.Listen(5) Console.WriteLine("Listen() is OK...") Console.WriteLine("Hello! I'm listening for connection...")
' Wait until a client connects ClientSocket = ListeningSocket.Accept() Console.WriteLine("Accept() is OK...")
' Create a NetworkStream for the accepted client connection NetStream = New NetworkStream(ClientSocket)
' Read the string "hello" from the stream since this was send before the serialized ' object. NetStream.Read(buffer, 0, 5) Console.WriteLine("Read() is OK...")
' Deserialize the object from the stream data = formatter.Deserialize(NetStream) Console.WriteLine("Deserialized the following object:") data.Print()
' Close up Try Console.WriteLine("Closing all...") ListeningSocket.Close() NetStream.Close() ClientSocket.Close() Catch ex As Exception Console.WriteLine("Error closing resources: " + ex.Message) End Try End Sub End Class |
Select the BinServerVB project folder> Right click mouse > Select Add Reference context menu.
Click the Projects tab > Select BinData > Click OK. This step is to resolve the BinData namespace in the BinServerVB project.
You can verify the added reference through the Project Dependencies as shown below.
Next, build the server project.
Make sure there is no error.
In order to test this project, we need to change the application type from DLL to EXE. Change the Application type: to Console Application and Startup object: to Sub Main.
|
|
Run the project. Select the BinServerVB folder > Right click mouse > Select Debug > Select Start new instance.
The following is the sample output.
The following output is the sample output when we run the program at the command prompt. In this case we need to copy the BinData.dll and the BinServerVB.exe and put them under the C:.
Rename the Class1 to BinClient.
Add the following client code.
' This is the client side to the socket serialization sample. This sample illustrates ' binary serialization over a socket stream. The client establishes a connection to ' the given server and serializes an instance of a BinDataClass class. ' ' Usage: ' executable_file_name [/server server-name] [/port port-number] ' ' Sample usage: ' executable_file_name /server myserver /port 5150 ' Imports System Imports System.Net Imports System.Net.Sockets Imports System.Runtime.Serialization Imports System.Runtime.Serialization.Formatters.Binary Imports BinData.BinData ' Common data structure to send on wire
Class BinClientClass
' Displays usage information for calling the client. Shared Sub usage() Console.WriteLine("usage: executable_file_name [/server server-name] [/port port-number]") End Sub
' Main application that parses the command line, resolves the server's host name, ' establishes a socket connection, and serializes the data to the server. ' ' <param name="args">Command line arguments passed to client</param> Shared Sub Main()
Dim ServerName As String = "localhost" Dim Port As Integer = 5150
usage()
' Parse command line arguments if any Dim args As String() = Environment.GetCommandLineArgs() Dim i As Integer
For i = 1 To args.Length - 1 Try If args(i) = "/server" Then ' The server's name we will connect to i = i + 1 ServerName = args(i)
ElseIf args(i) = "/port" Then ' The port on which the server is listening i = i + 1 Port = System.Convert.ToInt32(args(i)) End If
Catch e As System.IndexOutOfRangeException usage() Exit Sub End Try Next
' Attempt to resolve the server name specified Try
Dim ClientSocket As Socket = Nothing Dim IpHost As IPHostEntry Dim ServerEndPoint As IPEndPoint Dim ServerAndPort As String
IpHost = Dns.GetHostEntry(ServerName)
Console.WriteLine("Server name '{0}' resolved to {1} addresses", _ ServerName, IpHost.AddressList.Length())
' Walk the array of addresses return and attempt to connect to each ' one. Take the first successful connection and use it. Dim addr As IPAddress For Each addr In IpHost.AddressList ' Create the endpoint describing the address and port ServerEndPoint = New IPEndPoint(addr, Port)
If ServerEndPoint.AddressFamily = AddressFamily.InterNetwork Then ServerAndPort = addr.ToString() + ":" + Port.ToString() Else ServerAndPort = "[" + addr.ToString() + "]:" + Port.ToString() End If
Console.WriteLine("Attempting connection to {0}", ServerAndPort)
' Create a socket and attempt to connect to the endpoint ClientSocket = New Socket( _ ServerEndPoint.AddressFamily, _ SocketType.Stream, _ 0 _ ) Console.WriteLine("Client Socket() is OK...")
Try ClientSocket.Connect(ServerEndPoint) Console.WriteLine("Client Connect() is OK...") Catch err As SocketException Console.WriteLine("Connection attempt to {0} failed: {1}", _ ServerAndPort, _ err.Message() _ ) Console.WriteLine("Closing client socket...") ClientSocket.Close() ClientSocket = Nothing GoTo ContinueLoop End Try Exit For ContinueLoop: Next ' Make sure we have a valid socket connection before continuing If (Not IsNothing(ClientSocket)) And (ClientSocket.Connected = True) Then
Dim s As String = "Hello" Dim buf() As Byte = System.Text.Encoding.ASCII.GetBytes(s.ToCharArray()) Dim binclass As BinDataClass Dim NetStream As NetworkStream Dim formatter As IFormatter
binclass = New BinDataClass NetStream = New NetworkStream(ClientSocket) formatter = New BinaryFormatter
Try ' Send some data on socket before serializing the object. The server ' must consume this data before deserializing the objec otherwise ' a serialization exception will occur. ClientSocket.Send(buf)
binclass.Field2 = "Replaced original text with this message" Console.WriteLine("Serializing the following object:") binclass.Print() formatter.Serialize(NetStream, binclass) Catch err As SocketException Console.WriteLine("A socket error occurred: " + err.Message) Catch err As System.Runtime.Serialization.SerializationException Console.WriteLine("A serialization error occurred: " + err.Message) End Try ' Free up the resources NetStream.Close() End If ' Close socket resource. This check needs to be outside the previous ' control block since its possible a socket was created but the connect ' call failed. If Not IsNothing(ClientSocket) Then Console.WriteLine("Closing client socket...") ClientSocket.Close() ClientSocket = Nothing End If Catch err As SocketException ' This will catch DNS errors. If name resolution fails we might as well ' exit since we don't know the server's address. Console.WriteLine("Socket error: " + err.Message) End Try End Sub End Class |
Add the reference to the BinData.dll as done previously to resolve the BinData namespace.
To test this project we need to change the DLL to EXE type project. Change the Application type: to Console Application and Startup object: to Sub Main.
Build the project. Select the BinClientVB folder > Select Build. Make sure there is no error.
Run in Debug mode. Select the BinClientVB folder > Right click mouse > Select Debug > Select Start new instance.
The following is the sample output.
The following is the sample output when we run the project at the command prompt. In this case we need to copy the BinData.dll and the BinClientVB.exe (copied from the project’s Debug folder) and put them under the C:.
To test both the client and the server with shared DLL, firstly copy all the executables and put it under one folder. For example, in this case, we put them under C:\temp folder. Run the server program followed by the client.
Run the server program, start listening for connection.
Run the client program, serializing the objects.
The server de-serializes the objects.