< C# Client Socket Example (Cont...) | Main | VB .NET Client Socket Project Example (Cont...) >


 

Chapter 8 Part 5:

Client (and Server) Sockets Communication

 

 

What we have in this chapter 8 Part 5?

  1. VB .NET Simple Client Server Socket Program Example

  2. VB .NET: Adding Simple Client Socket Project Program Example

 

VB .NET Simple Client Server Socket Program Example

 

Create a new class library project and you might want to use the project and solution names as shown in the following Figure.

 

 

 

 

VB .NET Simple Server Socket Program Example - creating a new class library project in VS 2008

 

Rename the class to ServerSocket by renaming the source file to reflect the application that we are going to developed.

 

VB .NET Simple Server Socket Program Example - renaming the source file automatically renaming the class name

 

Add a new project to the Solution. Select the Solution folder > Right click mouse > Select Add context menu > Select New Project sub menu.

 

VB .NET Simple Server Socket Program Example - adding a new project to the existing project

 

VB .NET: Adding Simple Client Socket Project Program Example

 

Select a new class library project and name it as ClientSocketVB.

 

VB .NET Simple Server Socket Program Example - adding a new class library project to the existing solution

 

Rename the class to ClientSocket by renaming the source file.

 

VB .NET Simple Server Socket Program Example - renaming the source file

 

Add/edit the following Import directives at the top of the file.

 

Imports System

Imports System.Net

Imports System.Net.Sockets

 

Add the following code for the ServerSocket class that include the Main() subroutine.

 

 

 

 

' This is a simple TCP and UDP based server.

Public Class ServerSocket

    ' Winsock ioctl code which will disable ICMP errors from being propagated to a UDP socket.

    ' This can occur if a UDP packet is sent to a valid destination but there is no socket

    ' registered to listen on the given port.

    ' http://msdn.microsoft.com/en-us/library/bb736550(VS.85).aspx

    Public Const SIO_UDP_CONNRESET = -1744830452

 

    ' This routine repeatedly copies a string message into a byte array until filled.       

    ' <param name="dataBuffer">Byte buffer to fill with string message</param>

    ' <param name="message">String message to copy</param>

    Shared Sub FormatBuffer(ByVal dataBuffer As Byte(), ByVal message As String)

 

        Dim byteMessage As Byte() = System.Text.Encoding.ASCII.GetBytes(message)

        Dim index As Integer = 0

 

        ' First convert the string to bytes and then copy into send buffer

        While (index < dataBuffer.GetUpperBound(0))

            Dim j As Integer

            For j = 0 To byteMessage.GetUpperBound(0) - 1

                dataBuffer(index) = byteMessage(j)

                index = index + 1

 

                ' Make sure we don't go past the send buffer length

                If (index >= dataBuffer.GetUpperBound(0)) Then

                    GoTo AfterFor

                End If

            Next

AfterFor:

        End While

    End Sub

 

    ' Prints simple usage information.

    Shared Sub usage()

        Console.WriteLine("Executable_file_namee [-l bind-address] [-m message] [-n count] [-p port]")

        Console.WriteLine("                 [-t tcp|udp] [-x size]")

        Console.WriteLine("  -l bind-address        Local address to bind to")

        Console.WriteLine("  -m message             Text message to format into send buffer")

        Console.WriteLine("  -n count               Number of times to send a message")

        Console.WriteLine("  -p port                Local port to bind to")

        Console.WriteLine("  -t udp | tcp           Indicates which protocol to use")

        Console.WriteLine("  -x size                Size  of send and receive buffer")

        Console.WriteLine(".....Else default values will be used...")

        Console.WriteLine()

    End Sub

 

    ' <param name="args">Command line arguments</param>

    Shared Sub Main()

        Dim textMessage As String = "Server: ServerResponse"

        Dim localPort As Integer = 5150

        Dim sendCount As Integer = 10

        Dim bufferSize As Integer = 4096

        Dim localAddress As IPAddress = IPAddress.Any

        Dim sockType As SocketType = SocketType.Stream

        Dim sockProtocol As ProtocolType = ProtocolType.Tcp

 

        usage()

        Console.WriteLine()

 

        ' Parse the command line

        Dim args As String() = Environment.GetCommandLineArgs()

        Dim i As Integer

        For i = 1 To args.GetUpperBound(0)

            Try

                Dim CurArg() As Char = args(i).ToCharArray(0, args(i).Length)

                If (CurArg(0) = "-") Or (CurArg(0) = "/") Then

                    Select Case Char.ToLower(CurArg(1), System.Globalization.CultureInfo.CurrentCulture)

                        Case "l" ' Local interface to bind to

                            i = i + 1

                            localAddress = IPAddress.Parse(args(i))

                        Case "m"       ' Text message to put into the send buffer

                            i = i + 1

                            textMessage = args(i)

                        Case "p"       ' Port number for the destination

                            i = i + 1

                            localPort = System.Convert.ToInt32(args(i))

                        Case "t"       ' Specified TCP or UDP

                            i = i + 1

                            If (args(i) = "tcp") Then

                                sockType = SocketType.Stream

                                sockProtocol = ProtocolType.Tcp

                            ElseIf (args(i) = "udp") Then

                                sockType = SocketType.Dgram

                                sockProtocol = ProtocolType.Udp

                            Else

                                usage()

                                Exit Sub

                            End If

                        Case "x"       ' Size of the send and receive buffers

                            i = i + 1

                            bufferSize = System.Convert.ToInt32(args(i))

                        Case Else

                            usage()

                            Exit Sub

                    End Select

                End If

            Catch e As Exception

                usage()

                Exit Sub

            End Try

        Next

 

        Dim serverSocket As Socket = Nothing

 

        Try

            Dim localEndPoint As IPEndPoint = New IPEndPoint(localAddress, localPort)

            Dim senderAddress As IPEndPoint = New IPEndPoint(localAddress, 0)

            Dim castSenderAddress As EndPoint

            Dim clientSocket As Socket

            Dim receiveBuffer(bufferSize) As Byte

            Dim sendBuffer(bufferSize) As Byte

            Dim rc As Integer

 

            FormatBuffer(sendBuffer, textMessage)

 

            ' Create the server socket

            serverSocket = New Socket( _

                localAddress.AddressFamily, _

                sockType, _

                sockProtocol _

                )

            Console.WriteLine("Server: Socket() is OK...")

 

            ' Bind the socket to the local interface specified

            serverSocket.Bind(localEndPoint)

            Console.WriteLine("Server: Bind() is OK...")

 

            Console.WriteLine("Server: {0} server socket bound to {1}", sockProtocol.ToString(), localEndPoint.ToString())

 

            If (sockProtocol = ProtocolType.Tcp) Then

                ' If TCP socket, set the socket to listening

                serverSocket.Listen(1)

                Console.WriteLine("Server: Listen() is OK. I'm listening for connection...")

            Else

                Dim byteTrue(4) As Byte

 

                ' Set the SIO_UDP_CONNRESET ioctl to true for this UDP socket. If this UDP socket

                '    ever sends a UDP packet to a remote destination that exists but there is

                '    no socket to receive the packet, an ICMP port unreachable message is returned

                '    to the sender. By default, when this is received the next operation on the

                '    UDP socket that send the packet will receive a SocketException. The native

                '    (Winsock) error that is received is WSAECONNRESET (10054). Since we don't want

                '    to wrap each UDP socket operation in a try/except, we'll disable this error

                '    for the socket with this ioctl call.

                byteTrue(byteTrue.GetUpperBound(0) - 1) = 1

                serverSocket.IOControl(SIO_UDP_CONNRESET, byteTrue, Nothing)

                Console.WriteLine("Server: IOControl() is OK...")

            End If

 

            ' Service clients in a loop

            While (True)

                If (sockProtocol = ProtocolType.Tcp) Then

                    ' Wait for a client connection

                    clientSocket = serverSocket.Accept()

                    Console.WriteLine("Server: Accept() is OK...")

                    Console.WriteLine("Server: Accepted connection from: {0}", clientSocket.RemoteEndPoint.ToString())

 

                    ' Receive the request from the client in a loop until the client shuts

                    '    the connection down via a Shutdown.

                    Console.WriteLine("Server: Ready to receive using Receive()...")

                    While (True)

                        rc = clientSocket.Receive(receiveBuffer)

                        Console.WriteLine("Server: Read {0} bytes", rc)

                        If (rc = 0) Then

                            Exit While

                        End If

                    End While

 

                    ' Send the indicated number of response messages

                    Console.WriteLine("Server: Ready to send using Send()...")

                    For i = 0 To sendCount - 1

                        rc = clientSocket.Send(sendBuffer)

                        Console.WriteLine("Server: Sent {0} bytes", rc)

                    Next

 

                    ' Shutdown the client connection

                    clientSocket.Shutdown(SocketShutdown.Send)

                    Console.WriteLine("Server: Shutdown() is OK...")

 

                    clientSocket.Close()

                    Console.WriteLine("Server: Close() is OK")

 

                Else

                    castSenderAddress = CType(senderAddress, EndPoint)

 

                    ' Receive the initial request from the client

                    rc = serverSocket.ReceiveFrom(receiveBuffer, castSenderAddress)

                    Console.WriteLine("Server: ReceiveFrom() is OK...")

 

                    senderAddress = CType(castSenderAddress, IPEndPoint)

                    Console.WriteLine("Server: Received {0} bytes from {1}", rc, senderAddress.ToString())

 

                    ' Send the response to the client the requested number of times

                    Console.WriteLine("Server: Ready to send using SendTo()...")

                    For i = 0 To sendCount - 1

                        Try

                            rc = serverSocket.SendTo(sendBuffer, senderAddress)

                        Catch

                            ' If the sender's address is being spoofed we may get an error when sending

                            '    the response. You can test this by using IPv6 and using the RawSocket

                            '    sample to spoof a UDP packet with an invalid link local source address.

                            GoTo ContinueSendLoop

                        End Try

 

                        Console.WriteLine("Server: Sent {0} bytes to {1}", rc, senderAddress.ToString())

ContinueSendLoop:

                    Next

 

                    ' Send several zero byte datagrams to indicate to client that no more data

                    '    will be sent from the server. Multiple packets are sent since UDP

                    '    is not guaranteed and we want to try to make an effort the client

                    '    gets at least one.

                    Console.WriteLine("Server: Ready to send using SendTo(), sleeping for Sleep(250)...")

                    For i = 0 To 2

                        serverSocket.SendTo(sendBuffer, 0, 0, SocketFlags.None, senderAddress)

 

                        ' Space out sending the zero byte datagrams a bit. UDP is unreliable and

                        '   the local stack can even drop them before even hitting the wire!

                        System.Threading.Thread.Sleep(250)

                    Next

                End If

            End While

        Catch err As SocketException

            Console.WriteLine("Server: Socket error occurred: {0}", err.Message)

        Finally

            ' Close the socket if necessary

            If (Not IsNothing(serverSocket)) Then

                serverSocket.Close()

                Console.WriteLine("Server: Close() is OK...")

            End If

        End Try

    End Sub

End Class

 

Let change the DLL to EXE type program so that we can run it in console mode. Select the project folder > Right click mouse > Select Properties context menu.

 

VB .NET Simple Server Socket Program Example - invoking the project's property page

 

Change the Application type: to Console Application and the Startup object: to Sub Main.

 

VB .NET Simple Server Socket Program Example - changing the DLL to the EXE type application and setting up the startup to Main() subroutine

 

Next, build the project and make sure there is no error.

 

 

Then, run the project. Any error will be thrown by the exception handlers.

 

VB .NET Simple Client Server Socket Program Example - running the server project independently

 

The following is the sample output.

 

VB .NET Simple Client Server Socket Program Example - a sample output

 


< C# Client Socket Example (Cont...) | Main | VB .NET Client Socket Project Example (Cont...) >