< .NET IP Multicasting & C++ Example | Main | C# Multicast Program Example >

 


 

Chapter 8 Part 24:

Client (and Server) Sockets Communication

 

 

What do we have in this chapter 8 Part 24?

  1. C++ Multicast Program Example (Continue)

 

 

C++ Multicast Program Example (Continue)

 

Next, add usage() function.

 

/// <summary>

/// This method prints usage information for multicast sample

/// </summary>

static void usage()

{

    Console::WriteLine("Executable_file_name [/i ip] [/b ip] [/m ip] [/p port] [/x num] [/t text]");

    Console::WriteLine("              [/n count] [/s | /r]");

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

    Console::WriteLine("   /i ip                       Local interface to join multicast group(s) on");

    Console::WriteLine("   /b ip                      Local IP to bind the socket to");

    Console::WriteLine("   /m ip                     Multicast group to join");

    Console::WriteLine("   /p port                  Port to listen on or send to");

    Console::WriteLine("   /x size                  Length of send or receive buffer");

    Console::WriteLine("   /t text                    Text message to put in send buffer");

    Console::WriteLine("   /n count                Number of times to send or receive");

    Console::WriteLine("   /s                          Send data to a multicast group");

    Console::WriteLine("   /r                           Receive data send to the group");

    Console::WriteLine();

}

 

Finally, add the main() code.

 

/// <summary>

/// This is the main routine which parses the command line and creates the

/// multicast socket as given by the command line parameters. The sample

/// can either be invoked as a multicast sender or receiver.

///

/// To invoke as a multicast receiver:

///     multicast.exe /r /i 10.10.10.1 /m 234.6.6.6

/// To invoke as a multicast sender:

///     multicast.exe /s /i 10.10.10.99 /m 234.6.6.6

/// </summary>

/// <param name="appArguments">Command line arguments</param>

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

{

    MulticastEndpoint^ mcastEndpoint = gcnew MulticastEndpoint();

    String^ textMessage = "Hello Bastard World out there!";

    int port = 0, bufferLength = 1024, opCount = 10;

    bool isSender = true;

 

    // Parse the command line

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

    {

        try

        {

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

            {

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

                {

                    case 'b':

                        // Address to bind multicast socket to

                        mcastEndpoint->bindAddress = IPAddress::Parse(args[++i]);

                        break;

                    case 'c':

                        // How many times to send or receive

                        opCount = Convert::ToInt32(args[++i]->ToString());

                        break;

                    case 'i':

                        // Local interface to join group(s) on                               

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

                        break;

                    case 'm':

                        // Multicast group to join

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

                        break;

                    case 'p':

                        // Port number to bind to or send to

                        port = Convert::ToInt32(args[++i]->ToString());

                        break;

                    case 'r':

                        // Application invoked as receiver

                        isSender = false;

                        break;

                    case 's':

                        // Application invoked as sender

                        isSender = true;

                        break;

                    case 't':

                        // Text message to send

                        textMessage = args[++i];

                        break;

                    case 'x':

                        // Length of send/receive buffer

                        bufferLength = Convert::ToInt32(args[++i]->ToString());

                        break;

                    default:

                        usage();

                        return 0;

                }

            }

        }

        catch(Exception^ err)

        {

            Console::WriteLine("Error: " + err->Message);

            usage();

            return 0;

        }

    }

 

    // Make sure user specified at least on multicast group and interface to join

    if ((mcastEndpoint->multicastJoinList->Count == 0) || (mcastEndpoint->localInterfaceList->Count == 0))

    {

        Console::WriteLine("Please specify a multicast group and interface to join on!");

        usage();

        return 0;

    }

 

    // Now, create the multicast socket

    Console::WriteLine("Creating the multicast socket...");

    try

    {

        if (isSender == true)

        {

            // For the sender, we don't care what the local port the socket is bound to

            mcastEndpoint->Create(

                0,               // If the sender we don't care what local port we bind to

                bufferLength

                );

        }

        else

        {

            mcastEndpoint->Create(port, bufferLength);

        }

 

        if (isSender == true)

        {

            IPEndPoint^ destinationGroup = gcnew IPEndPoint((IPAddress^)mcastEndpoint->multicastJoinList[0], port);

            int rc;

 

            // Set the send interface for all outgoing multicast packets

            Console::WriteLine("Setting the send interface for all outgoing multicast packets...");

            mcastEndpoint->SetSendInterface((IPAddress^)mcastEndpoint->localInterfaceList[0]);

            mcastEndpoint->FormatBuffer(textMessage);

 

            // Send the message the requested number of times

            Console::WriteLine("Sending the message the requested number of times...");

            for (int i = 0; i < opCount; i++)

            {

                try

                {

                    rc = mcastEndpoint->mcastSocket->SendTo(mcastEndpoint->dataBuffer, destinationGroup);

                    Console::Write("Multicast SendTo() is OK. ");

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

                }

                catch (SocketException^ err)

                {

                      Console::WriteLine("Multiast SendTo() failed: " + err->Message);

                }

            }

        }

        else

        {

            IPEndPoint^ senderEndPoint = gcnew IPEndPoint((IPAddress^)mcastEndpoint->localInterfaceList[0], 0);

            EndPoint^ castSenderEndPoint = (EndPoint^)senderEndPoint;

            int rc;

 

            for (int i = 0; i < opCount; i++)

            {

                try

                {

                    rc = mcastEndpoint->mcastSocket->ReceiveFrom(mcastEndpoint->dataBuffer, castSenderEndPoint);

                    Console::Write("Multicast ReceiveFrom() is OK...");

                    // Setting to an instance of an object before using it

                    senderEndPoint = (IPEndPoint^)castSenderEndPoint;

 

                        Console::WriteLine("Received {0} bytes from {1}: '{2}'\n",

                        rc,

                        senderEndPoint->ToString(),

                        Text::Encoding::ASCII->GetString(mcastEndpoint->dataBuffer, 0, rc)

                        );

                }

                catch (SocketException^ err)

                {

                     Console::WriteLine("Multicast ReceiveFrom() failed: " + err->Message);

                }

            }

        }

        // Drop membership to groups. This isn't required in this sample as closing the socket

        //    will implicitly leave all groups joined, but it's a good practice.

        mcastEndpoint->LeaveGroups();

    }

    catch(Exception^ err)

    {

       Console::WriteLine("An error occurred creating the multicast socket: " + err->Message);

    }

    finally

    {

        if (mcastEndpoint->mcastSocket != nullptr)

        {

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

            mcastEndpoint->mcastSocket->Close();

        }

        mcastEndpoint = nullptr;

    }

    return 0;

}

 

Build the project and make sure there is no error. Run the project. Any error will be thrown by the exception handlers. The following is the sample output.

 

C++ Multicast Program Example - a sample output without any argument

 

The following sample output shows the program as a receiver.

 

C++ Multicast Program Example - a sample output with arguments acts as receiver  

 

The following sample output shows the program as a sender.

 

C++ Multicast Program Example - a sample output with arguments acts as sender

 

The following are sample outputs show the sender and receiver. This program example was tested on a simple private network with two computers connected using the peer-to-peer cable (cross cable). You may want to test on the real network with more receivers that will resemble the chat system. Firstly, we run the receiver.

 

C++ Multicast Program Example - a sample output running as receiver, waiting for connection

 

Then, we run the sender.

 

C++ Multicast Program Example - a sample output as sender

 

The following is the receiver output screenshot when the communication was completed.

 

C++ Multicast Program Example - a sample of receiver output when the communication was completed

 

 

 


 

< .NET IP Multicasting & C++ Example | Main | C# Multicast Program Example >