< C# & VB .NET TCP Client Examples | Main | VB .NET UDP Client-Server Example & Code Access Security >

 


 

Chapter 8 Part 31:

Client (and Server) Sockets Communication

 

 

What do we have in this chapter 8 Part 31?

  1. C++ UDP Client and Server Program Example

  2. C# UDP Client and Server Program Example

 

 

C++ UDP Client and Server Program Example

 

Create a new CLR console application project and you might want to use UDPClientServerCP as the name.

 

C++ UDP Client and Server Program Example - creating a new CLR console application project in Visual Studio IDE

 

 

Add the following code.

 

// UDPClientServerCP.cpp : main project file.

#include "stdafx.h"

 

using namespace System;

using namespace System::Net;

using namespace System::Net::Sockets;

using namespace System::Collections;

 

static public void usage()

{

    Console::WriteLine("Usage: UdpClientSampleCS [-m mcast] [-l local-ip] [-n count]");

    Console::WriteLine("                           [-p port] [-r] [-s destination] [-x size]\n");

    Console::WriteLine("Available options:");

    Console::WriteLine("     -m mcast            Multicast group to join. May be specified multiple");

    Console::WriteLine("                            times. For IPv6 include interface to join group on");

    Console::WriteLine("                            as the scope id (e.g. ff12::1%4)");

    Console::WriteLine("     -l local-ip         Local IP address to bind to");

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

    Console::WriteLine("     -p port             Port number: local port for receiver, remote port for sender");

    Console::WriteLine("     -r                  Receive UDP data");

    Console::WriteLine("     -s destination      Send UDP data to given destination");

    Console::WriteLine("     -x size             Size of send and receive buffers");

    Console::WriteLine();

}

 

int main(array<System::String ^> ^args)

{

    ArrayList^ multicastGroups = gcnew ArrayList();

    IPAddress^ localAddress = IPAddress::Any;

    IPAddress^ destAddress = nullptr;

    unsigned short portNumber = 5150;

    bool udpSender = false;

    int bufferSize = 256, sendCount = 5, i;

 

    // Parse the command line

    if(args->Length != 0)

    {

    for (i = 0; i < args->Length; i++)

    {

        try

        {

            if ((args[i][0] == '-') || (args[i][0] == '/'))

            {

                switch (Char::ToLower(args[i][1]))

                {

                    case 'm':       // Multicast groups to join

                        multicastGroups->Add(IPAddress::Parse(args[++i]));

                        break;

                    case 'l':       // Local interface to bind to

                        localAddress = IPAddress::Parse(args[++i]);

                        break;

                    case 'n':       // Number of times to send the response

                        sendCount = Convert::ToInt32(args[++i]);

                        break;

                    case 'p':       // Port number (local for receiver, remote for sender)

                        portNumber = Convert::ToUInt16(args[++i]);

                        break;

                    case 'r':       // Indicates UDP receiver

                        udpSender = false;

                        break;

                    case 's':       // Indicates UDP sender as well as the destination address

                        udpSender = true;

                        destAddress = IPAddress::Parse(args[++i]);

                        break;

                    case 'x':       // Size of the send and receive buffers

                        bufferSize = Convert::ToInt32(args[++i]);

                        break;

                    default:

                        usage();

                        return 0;

                }

            }

        }

        catch(Exception^ err)

        {

            Console::WriteLine("Error lor!!!: {0}", err->Message);

            usage();

            return 0;

        }

    }

      }

      else

      {

             usage();

         return 0;

      }

 

    UdpClient^ udpSocket = nullptr;

    array<Byte>^ sendBuffer = gcnew array<Byte>(bufferSize);

    array<Byte>^ receiveBuffer = gcnew array<Byte>(bufferSize);

    int rc;

 

    try

    {

        // Create an unconnected socket since if invoked as a receiver we don't necessarily

        //    want to associate the socket with a single endpoint. Also, for a sender socket

        //    specify local port of zero (to get a random local port) since we aren't receiving anything.

        Console::WriteLine("Creating connectionless socket...");

        if (udpSender == false)

            udpSocket = gcnew UdpClient(gcnew IPEndPoint(localAddress, portNumber));

        else

            udpSocket = gcnew UdpClient(gcnew IPEndPoint(localAddress, 0));

 

        // Join any multicast groups specified

        Console::WriteLine("Joining any multicast groups specified...");

        for (i = 0; i < multicastGroups->Count; i++)

        {

            if (localAddress->AddressFamily == AddressFamily::InterNetwork)

            {

                // For IPv4 multicasting only the group is specified and not the

                //    local interface to join it on. This is bad as on a multihomed

                //    machine, the application won't really know which interface

                //    it is joined on (and there is no way to change it via the UdpClient).

                udpSocket->JoinMulticastGroup((IPAddress^)multicastGroups[i]);

            }

            else if (localAddress->AddressFamily == AddressFamily::InterNetworkV6)

            {

                // For some reason, the IPv6 multicast join allows the local interface index

                //    to be specified such that the application can join multiple groups on

                //    any interface which is great (but lacking in IPv4 multicasting with the

                //    UdpClient). IPv6 multicast groups should be specified with the scope id

                //    when passed on the command line (e.g. fe80::1%4).

                udpSocket->JoinMulticastGroup((int)((IPAddress^)multicastGroups[i])->ScopeId, (IPAddress^)multicastGroups[i]);

            }

        }

 

        // If you want to send data with the UdpClient it must be connected -- either by

        //    specifying the destination in the UdpClient constructor or by calling the

        //    Connect method. You can call the Connect method multiple times to associate

        //    a different endpoint with the socket.

        if (udpSender == true)

        {

            udpSocket->Connect(destAddress, portNumber);

            Console::WriteLine("Connect() is OK...");

        }

 

        if (udpSender == true)

        {

            // Send the requested number of packets to the destination

            Console::WriteLine("Sending the requested number of packets to the destination, Send()...");

            for (i = 0; i < sendCount; i++)

            {

                rc = udpSocket->Send(sendBuffer, sendBuffer->Length);

                Console::WriteLine("Sent {0} bytes to {1}", rc, destAddress->ToString());

            }

            // Send a few zero length datagrams to indicate to the receive to exit. Put a short

            //    sleep between them since UDP is unreliable and zero byte datagrams are really

            //    fast (and the local stack can actually drop datagrams before they even make it

            //    onto the wire).

            Console::WriteLine("Having some sleep, Sleep(250)...");

            for (i = 0; i < 3; i++)

            {

                rc = udpSocket->Send(sendBuffer, 0);

                Threading::Thread::Sleep(250);

            }

        }

        else

        {

            IPEndPoint^ senderEndPoint = gcnew IPEndPoint(localAddress, 0);

            // Receive datagrams in a loop until a zero byte datagram is received.

            //    Note the difference with the UdpClient in that the source address

            //    is simply an IPEndPoint that doesn't have to be cast to and EndPoint

            //    object as is the case with the Socket class.

            Console::WriteLine("Receiving datagrams in a loop until a zero byte datagram is received...");

            while (true)

            {

                receiveBuffer = udpSocket->Receive(senderEndPoint);

                Console::WriteLine("Read {0} bytes from {1}", receiveBuffer->Length, senderEndPoint->ToString());

                if (receiveBuffer->Length == 0)

                    break;

            }

        }

    }

    catch (SocketException^ err)

    {

            Console::WriteLine("Socket error occurred: {0}", err->Message);

            Console::WriteLine("Stack: {0}", err->StackTrace);

    }

    finally

    {

        if (udpSocket != nullptr)

        {

            // Clean things up by dropping any multicast groups we joined

            Console::WriteLine("Cleaning things up by dropping any multicast groups we joined...");

            for (i = 0; i < multicastGroups->Count; i++)

            {

                if (localAddress->AddressFamily == AddressFamily::InterNetwork)

                {

                    udpSocket->DropMulticastGroup((IPAddress^)multicastGroups[i]);

                }

                else if (localAddress->AddressFamily == AddressFamily::InterNetworkV6)

                {

                    // IPv6 multicast groups should be specified with the scope id when passed

                    //    on the command line

                    udpSocket->DropMulticastGroup((IPAddress^)multicastGroups[i], (int)((IPAddress^)multicastGroups[i])->ScopeId);

                }

            }

            // Free up the underlying network resources

            Console::WriteLine("Closing the socket...");

            udpSocket->Close();

        }

    }

    return 0;

}

 

Next, build the project and make sure there is no error. Then, run the project. Any error will be thrown by the exception handlers. The following is the sample output.

 

C++ UDP Client and Server Program Example - a sample output

 

The following is the output sample when we run it as sender from the command prompt.

 

C++ UDP Client and Server Program Example - the output sample when we run it as sender from the command prompt

 

The following is the output sample when we run it both as a receiver and as a sender. Firstly, we run the program as a receiver from the C:\.

 

C++ UDP Client and Server Program Example - the output sample when we run it as receiver from the command prompt

 

Then, we run the same program from other path as a sender.

 

C++ UDP Client and Server Program Example - the output sample when we run it as sender at the command prompt from another directory in the same host for testing

 

The following screenshot shows the UDP as a receiver when the communication was completed.

 

C++ UDP Client and Server Program Example - the output sample screenshot shows the UDP as a receiver when the communication was completed

 

 

 

C# UDP Client and Server Program Example

 

Create a new console application project and you might want to use UdpClientSampleCS as the name.

 

C# UDP Client and Server Program Example - creating a new console application project in Visual Studio 2008 IDE

 

Next, rename the class to UdpClientSample by renaming the source file.

 

C# UDP Client and Server Program Example - renaming the source file

 

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

 

using System;

using System.Net;

using System.Net.Sockets;

using System.Collections;

 

Add the following usage() method in side the class.

 

static public void usage()

{

            Console.WriteLine("Usage: UdpClientSampleCS [-m mcast] [-l local-ip] [-n count]");

            Console.WriteLine("                           [-p port] [-r] [-s destination] [-x size]");

            Console.WriteLine();

            Console.WriteLine("Available options:");

            Console.WriteLine("     -m mcast            Multicast group to join. May be specified multiple");

            Console.WriteLine("                            times. For IPv6 include interface to join group on");

            Console.WriteLine("                            as the scope id (e.g. ff12::1%4)");

            Console.WriteLine("     -l local-ip         Local IP address to bind to");

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

            Console.WriteLine("     -p port             Port number: local port for receiver, remote port for sender");

            Console.WriteLine("     -r                  Receive UDP data");

            Console.WriteLine("     -s destination      Send UDP data to given destination");

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

            Console.WriteLine();

}

 

Add the Main() code.

 

 

        static void Main(string[ ] args)

        {

            ArrayList multicastGroups = new ArrayList();

            IPAddress localAddress = IPAddress.Any, destAddress = null;

            ushort portNumber = 5150;

            bool udpSender = false;

            int bufferSize = 256, sendCount = 5, i;

 

            usage();

 

            // Parse the command line

            for (i = 0; i < args.Length; i++)

            {

                try

                {

                    if ((args[i][0] == '-') || (args[i][0] == '/'))

                    {

                        switch (Char.ToLower(args[i][1]))

                        {

                            case 'm':       // Multicast groups to join

                                multicastGroups.Add(IPAddress.Parse(args[++i]));

                                break;

                            case 'l':       // Local interface to bind to

                                localAddress = IPAddress.Parse(args[++i]);

                                break;

                            case 'n':       // Number of times to send the response

                                sendCount = System.Convert.ToInt32(args[++i]);

                                break;

                            case 'p':       // Port number (local for receiver, remote for sender)

                                portNumber = System.Convert.ToUInt16(args[++i]);

                                break;

                            case 'r':       // Indicates UDP receiver

                                udpSender = false;

                                break;

                            case 's':       // Indicates UDP sender as well as the destination address

                                udpSender = true;

                                destAddress = IPAddress.Parse(args[++i]);

                                break;

                            case 'x':       // Size of the send and receive buffers

                                bufferSize = System.Convert.ToInt32(args[++i]);

                                break;

                            default:

                                usage();

                                return;

                        }

                    }

                }

                catch

                {

                    usage();

                    return;

                }

            }

            UdpClient udpSocket = null;

            byte[ ] sendBuffer = new byte[bufferSize], receiveBuffer = new byte[bufferSize];

            int rc;

 

            try

            {

                // Create an unconnected socket since if invoked as a receiver we don't necessarily

                //    want to associate the socket with a single endpoint. Also, for a sender socket

                //    specify local port of zero (to get a random local port) since we aren't receiving

                //    anything.

                Console.WriteLine("Creating connectionless socket...");

                if (udpSender == false)

                    udpSocket = new UdpClient(new IPEndPoint(localAddress, portNumber));

                else

                    udpSocket = new UdpClient(new IPEndPoint(localAddress, 0));

 

                // Join any multicast groups specified

                Console.WriteLine("Joining any multicast groups specified...");

                for (i = 0; i < multicastGroups.Count; i++)

                {

                    if (localAddress.AddressFamily == AddressFamily.InterNetwork)

                    {

                        // For IPv4 multicasting only the group is specified and not the

                        //    local interface to join it on. This is bad as on a multihomed

                        //    machine, the application won't really know which interface

                        //    it is joined on (and there is no way to change it via the UdpClient).

                        udpSocket.JoinMulticastGroup((IPAddress)multicastGroups[i]);

                    }

                    else if (localAddress.AddressFamily == AddressFamily.InterNetworkV6)

                    {

                        // For some reason, the IPv6 multicast join allows the local interface index

                        //    to be specified such that the application can join multiple groups on

                        //    any interface which is great (but lacking in IPv4 multicasting with the

                        //    UdpClient). IPv6 multicast groups should be specified with the scope id

                        //    when passed on the command line (e.g. fe80::1%4).

                        udpSocket.JoinMulticastGroup((int)((IPAddress)multicastGroups[i]).ScopeId, (IPAddress)multicastGroups[i]);

                    }

                }

 

                // If you want to send data with the UdpClient it must be connected -- either by

                //    specifying the destination in the UdpClient constructor or by calling the

                //    Connect method. You can call the Connect method multiple times to associate

                //    a different endpoint with the socket.

                if (udpSender == true)

                {

                    udpSocket.Connect(destAddress, portNumber);

                    Console.WriteLine("Connect() is OK...");

                }

 

                if (udpSender == true)

                {

                    // Send the requested number of packets to the destination

                    Console.WriteLine("Sending the requested number of packets to the destination, Send()...");

                    for (i = 0; i < sendCount; i++)

                    {

                        rc = udpSocket.Send(sendBuffer, sendBuffer.Length);

                        Console.WriteLine("Sent {0} bytes to {1}", rc, destAddress.ToString());

                    }

                    // Send a few zero length datagrams to indicate to the receive to exit. Put a short

                    //    sleep between them since UDP is unreliable and zero byte datagrams are really

                    //    fast (and the local stack can actually drop datagrams before they even make it

                    //    onto the wire).

                    Console.WriteLine("HAving some sleep, Sleep(250)...");

                    for (i = 0; i < 3; i++)

                    {

                        rc = udpSocket.Send(sendBuffer, 0);

                        System.Threading.Thread.Sleep(250);

                    }

                }

                else

                {

                    IPEndPoint senderEndPoint = new IPEndPoint(localAddress, 0);

                    // Receive datagrams in a loop until a zero byte datagram is received.

                    //    Note the difference with the UdpClient in that the source address

                    //    is simply an IPEndPoint that doesn't have to be cast to and EndPoint

                    //    object as is the case with the Socket class.

                    Console.WriteLine("Receiving datagrams in a loop until a zero byte datagram is received...");

                    while (true)

                    {

                        receiveBuffer = udpSocket.Receive(ref senderEndPoint);

                        Console.WriteLine("Read {0} bytes from {1}", receiveBuffer.Length, senderEndPoint.ToString());

 

                        if (receiveBuffer.Length == 0)

                            break;

                    }

                }

            }

            catch (SocketException err)

            {

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

                Console.WriteLine("Stack: {0}", err.StackTrace);

            }

            finally

            {

                if (udpSocket != null)

                {

                    // Clean things up by dropping any multicast groups we joined

                    Console.WriteLine("Cleaning things up by dropping any multicast groups we joined...");

                    for (i = 0; i < multicastGroups.Count; i++)

                    {

                        if (localAddress.AddressFamily == AddressFamily.InterNetwork)

                        {

                            udpSocket.DropMulticastGroup((IPAddress)multicastGroups[i]);

                        }

                        else if (localAddress.AddressFamily == AddressFamily.InterNetworkV6)

                        {

                            // IPv6 multicast groups should be specified with the scope id when passed

                            //    on the command line

                            udpSocket.DropMulticastGroup(

                                (IPAddress)multicastGroups[i],

                                (int)((IPAddress)multicastGroups[i]).ScopeId

                                );

                        }

                    }

                    // Free up the underlying network resources

                    Console.WriteLine("Closing the socket...");

                    udpSocket.Close();

                }

            }

        }

 

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

 

C# UDP Client and Server Program Example - building the project using the VS 2008 Build Solution menu  

 

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

 

C# UDP Client and Server Program Example - running the project

 

The following is the sample output.

 

C# UDP Client and Server Program Example - a sample output with default argument values

 

The following are the output samples when we run it as sender at the command prompt.

 

C# UDP Client and Server Program Example - running the udp program as a sender

 

 

C# UDP Client and Server Program Example - another output sample of the udp program as a sender

 

The following is the output sample when we run it as receiver at the command prompt.

 

C# UDP Client and Server Program Example - running the UDP program as a receiver

 

Running both the receiver and the sender. Firstly we run the program as a receiver.

 

C# UDP Client and Server Program Example - running the UDP program as a receiver to test the sender

 

Then, we run the same program from another path as a sender.

 

C# UDP Client and Server Program Example - running the UDP program as a sender from other path of the same host to test the sender

 

The following screenshot shows the UDP as a receiver when the communication was completed.

 

C# UDP Client and Server Program Example - the sample output of the UDP receiver when communication was completed

 

 

 


 

< C# & VB .NET TCP Client Examples | Main | VB .NET UDP Client-Server Example & Code Access Security >