< Intro To TCP & UDP In .NET | Main | C# Client Socket Program Example >


 

Chapter 8 Part 2:

Client (and Server) Sockets Communication

 

 

What do we have in this chapter 8 Part 2?

  1. C++ Simple Client Socket Program Example

 

C++ Simple Client Socket Program Example

 

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

 

C++ Simple Client Socket Program Example - a new CLR console application project creation in VS 2008

 

Add the following code.

 

// SimpleSocketClientCP.cpp : main project file.

/// <summary>

/// This is a simple TCP and UDP based client.

/// </summary>

 

#include "stdafx.h"

 

using namespace System;

using namespace System::Net;

using namespace System::Net::Sockets;

 

/// <summary>

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

/// </summary>

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

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

static public void FormatBuffer(array<Byte>^ dataBuffer, String^ message)

{

    array<Byte>^ byteMessage = Text::Encoding::ASCII->GetBytes(message);

    int index = 0;

 

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

    while (index < dataBuffer->Length)

    {

        for (int j = 0; j < byteMessage->Length; j++)

        {

            dataBuffer[index] = byteMessage[j];

            index++;

 

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

            if (index >= dataBuffer->Length)

            {

                break;

            }

        }

    }

            Console::Write(message + "\n");

}

 

/// <summary>

/// Prints simple usage information.

/// </summary>

static public void usage()

{

    Console::WriteLine("usage: Executable_file_name [-c] [-n server] [-p port] [-m message]");

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

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

    Console::WriteLine("     -c              If UDP connect the socket before sending");

    Console::WriteLine("     -n server       Server name or address to connect/send to");

    Console::WriteLine("     -p port         Port number to connect/send to");

    Console::WriteLine("     -m message      String message to format in request buffer");

    Console::WriteLine("     -t tcp|udp      Indicates to use either the TCP or UDP protocol");

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

}

 

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

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

{

    // Initialize to the default values

    SocketType sockType = SocketType::Stream;

    ProtocolType sockProtocol = ProtocolType::Tcp;

    String^ remoteName = "localhost";

    String^ textMessage = "Client: This is a test message from client!";

    bool udpConnect = false;

    int remotePort = 5150, bufferSize = 4096;

 

    if(args->Length != 0)

    {

    // 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 'c':       // "Connect" the UDP socket to the destination

                        udpConnect = true;

                        break;

                    case 'n':       // Destination address to connect to or send to

                        remoteName = args[++i];

                        break;

                    case 'm':       // Text message to put into the send buffer

                        textMessage = args[++i];

                        break;

                    case 'p':       // Port number for the destination

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

                        break;

                    case 't':       // Specified TCP or UDP

                        i++;

                        if (String::Compare(args[i], "tcp", true) == 0)

                        {

                             sockType = SocketType::Stream;

                             sockProtocol = ProtocolType::Tcp;

                        }

                        else if (String::Compare(args[i], "udp", true) == 0)

                        {

                             sockType = SocketType::Dgram;

                             sockProtocol = ProtocolType::Udp;

                        }

                        else

                        {

                            usage();

                            return 0;

                        }

                        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: {0}.", err->Message);

            usage();

            return 0;

        }

    }

}

else

{

     usage();

     return 0;

}

 

    Socket^ clientSocket = nullptr;

    IPHostEntry^ resolvedHost = nullptr;

    IPEndPoint^ destination = nullptr;

 

    // Setting-up buffers

    Console::WriteLine("Client: Setting up receive and send buffers...");

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

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

    int rc;

 

    // Format the string message into the send buffer

    Console::WriteLine("Client: Formatting the string message into the send buffer...");

    FormatBuffer(sendBuffer, textMessage);

 

    try

    {

        // Try to resolve the remote host name or address

        Console::WriteLine("Client: Resolving the remote host name or address...");

        resolvedHost = Dns::GetHostEntry(remoteName);

        Console::WriteLine("Client: GetHostEntry() is OK...");

 

 

 

 

        // Try each address returned

        Console::WriteLine("Client: Trying each available address returned & creating socket...");

        for each (IPAddress^ addr in resolvedHost->AddressList)

        {

            // Create a socket corresponding to the address family of the resolved address

            clientSocket = gcnew Socket(addr->AddressFamily, sockType, sockProtocol);

            Console::WriteLine("Client: Socket() is OK...");

            try

            {

                // Create the endpoint that describes the destination

                Console::WriteLine("Client: Creating the destination endpoint...");

                destination = gcnew IPEndPoint(addr, remotePort);

                Console::WriteLine("Client: IPEndPoint() is OK. IP Address: {0}, server port: {1}", addr, remotePort);

 

                if ((sockProtocol == ProtocolType::Udp) && (udpConnect == false))

                {

                    Console::WriteLine("Client: UDP - Destination address is: {0}", destination);

                    break;

                }

                else

                {

                     Console::WriteLine("Client: TCP - Attempting connection to: {0}", destination);

                }

                clientSocket->Connect(destination);

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

                break;

            }

            catch (SocketException^ err)

            {

                // Connect failed so close the socket and try the next address

                clientSocket->Close();

                Console::WriteLine("Client: Client socket closed. Error code: " + err->ErrorCode);

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

                clientSocket = nullptr;

                continue;

            }

        }

 

        // Make sure we have a valid socket before trying to use it

        if ((clientSocket != nullptr) && (destination != nullptr))

        {

            try

            {

                // Send the request to the server

                if ((sockProtocol == ProtocolType::Udp) && (udpConnect == false))

                {

                    clientSocket->SendTo(sendBuffer, destination);

                    Console::WriteLine("Client: UDP - SendTo() is OK...");

                }

                else

                {

                    rc = clientSocket->Send(sendBuffer);

                    Console::WriteLine("Client: TCP - send() is OK...");

                    Console::WriteLine("Client: Sent request of {0} bytes", rc);

 

                    // For TCP, shutdown sending on our side since the client won't send any more data

                    if (sockProtocol == ProtocolType::Tcp)

                    {

                        clientSocket->Shutdown(SocketShutdown::Send);

                        Console::WriteLine("Client: Shutdown() is OK...");

                    }

                }

 

                // Receive data in a loop until the server closes the connection. For

                //    TCP this occurs when the server performs a shutdown or closes

                //    the socket. For UDP, we'll know to exit when the remote host

                //    sends a zero byte datagram.

                while (true)

                {

                    if ((sockProtocol == ProtocolType::Tcp) || (udpConnect == true))

                    {

                        rc = clientSocket->Receive(recvBuffer);

                        Console::WriteLine("Client: Receive() is OK...");

                        Console::WriteLine("Client: Read {0} bytes", rc);

                    }

                    else

                    {

                        IPEndPoint^ fromEndPoint = gcnew IPEndPoint(destination->Address, 0);

                        Console::WriteLine("Client: IPEndPoint() is OK...");

                        EndPoint^ castFromEndPoint = (EndPoint^)fromEndPoint;

                        rc = clientSocket->ReceiveFrom(recvBuffer, castFromEndPoint);

                        Console::WriteLine("Client: ReceiveFrom() is OK...");

                        fromEndPoint = (IPEndPoint^)castFromEndPoint;

                        Console::WriteLine("Client: Read {0} bytes from {1}", rc, fromEndPoint);

                    }

 

                    // Exit loop if server indicates shutdown

                    if (rc == 0)

                    {

                        clientSocket->Close();

                        Console::WriteLine("Client: Close() is OK...");

                        break;

                    }

                }

 

           }

            catch (SocketException^ err)

            {

                Console::WriteLine("Client: Error occurred while sending or receiving data.");

                Console::WriteLine("   Error: {0}, code: {1}", err->Message, err->ErrorCode);

            }

        }

        else

        {

           Console::WriteLine("Client: Unable to establish connection to server!");

        }

    }

    catch (SocketException^ err)

    {

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

    }

    return 0;

}

 

Build and run the project. The following are the output samples when the executable run at the command prompt.

 

C++ Simple Client Socket Program Example - a sample output

 

Next, let test this client program with the server program that previously created. Firstly run the server program. The server is listening for client connection.

 

C++ Simple Client Socket Program Example - a sample output with TCP protocol of the server program ready for connection

 

Then, run the client program using the same protocol (TCP) and connecting to the port that the server is listening. The following is the output sample.

 

C++ Simple Client Socket Program Example - a sample output with TCP client connection in action

 

The following is the receiver/server output screenshot when the communication was completed. You may want to test this program on real network.

 

C++ Simple Client Socket Program Example - a sample output of the TCP server when the communication was completed

 

C++ Simple Client Socket Program Example - a sample output of the TCP server when the communication was completed - continue

 

The following output samples show the UDP protocol.

 

 

 

 

C++ Simple Client Socket Program Example - a sample output of the UDP server, ready for connection

 

C++ Simple Client Socket Program Example - a sample output of the UDP client, connected to the server

 

C++ Simple Client Socket Program Example - a sample output of the UDP server, when the communication was completed

 


< Intro To TCP & UDP In .NET | Main | C# Client Socket Program Example >