• Skip to main content
  • Skip to header right navigation
  • Skip to site footer
CDP Studio logo

CDP Studio

The no-code and full-code software development tool for distributed control systems and HMI

  • Why CDP
    • Software developers
    • Automation engineers
    • Managers
  • Product
    • Design UI
    • Develop
    • Analyze and test
    • Deploy
    • Framework and toolbox
    • Compatibility
  • Services
  • Use cases
  • Pricing
  • Try CDP

CDP Studio Documentation

  • Framework - CDP Core
  • TCPConnection
  • 4.11.14

TCPConnection Class

The TCPConnection class represents a Transmission Control Protocol (TCP) connection. More...

Header: #include <OSAPI/Network/TCPConnection.h>
Inherited By:

CDP::IO::TCPTransport

  • List of all members, including inherited members

Public Functions

TCPConnection()
TCPConnection(const TCPConnection &oldConnection)
virtual ~TCPConnection()
int CloseSocket()
int ConnectTo(IpAddress ipAddressLocal, IpAddress ipAddressRemote)
void EnableReuse(bool bReuse)
virtual unsigned int GetInterfaceNo()
IpAddress &GetLocalAddress() const
unsigned int GetNrBytesPending() const
IpAddress &GetRemoteAddress() const
SOCKET GetSocket() const
virtual int GetTCPmaxTransferUnitBody()
bool IsConnected() const
bool IsSocketError() const
bool IsSocketReadReady(int nTimeoutMs) const
bool IsSocketWriteReady(int nTimeoutMs) const
void Listen(IpAddress ipAddressLocal)
bool MulticastJoin(IpAddress &multicastGroup, IpAddress &localInterface)
bool MulticastLeave(IpAddress &multicastGroup, IpAddress &localInterface)
int OpenSocket()
void Read(char *pData, int &length)
int Send(const char *pData, int &length)
void SetAsCloseToRealTimeAsPossible()
void SetBlockingMode(bool bBlocking)
void SetBlockingMode(SOCKET specSocket, bool bBlocking)
bool SetMulticastTTL(int timeToLive)
void SetRemoteAddress(IpAddress &remoteIpAddress)
int SetSocket(SOCKET newSocket, bool isConnected = true, sockaddr *localAddress = NULL)
int SetSocket(SOCKET newSocket, IpAddress &localAddress, bool isConnected = true)
virtual void SetTCPmaxTransferUnitBody(int newTCPmaxTransferUnitBody)
void ShutDown()
int WaitForIncomingConnection(TCPConnection &newConnection) const
TCPConnection &operator=(const TCPConnection &oldConnection)

Detailed Description

The TCPConnection class represents a Transmission Control Protocol (TCP) connection.

Usage

  • Create a socket with OpenSocket().
  • Connect to either:
    • remote (listening) port by ConnectTo(), or
    • open a listening port by calling Listen(), then wait for incoming connections by calling WaitForIncomingConnection().
  • Read or send data with Read() or Send().
  • Call ShutDown() to gracefully shut down the connection.
  • Close the socket with CloseSocket().
  • Must use try/catch around calls to TCPConnection class as methods will throw TCPException.

Example

This example uses seprate thread to communicate via TCPConnection. The drawback with the code is that WaitForIncomingConnection() and Read() will block infinetly if no connection is made, so it is not possible to stop the thread in a good way. Using CloseSocket() from another thread is not a good solution as it tends to crash (at least on some OS's).

Note: All (int) return values are 0 if successful, nonzero otherwise.

The example header file tcpconnectionthread.h looks like this:

#include <OSAPI/Process/OSAPIThread.h>
#include <OSAPI/Network/TCPConnection.h>

class TCPConnectionThread : public OSAPIThread
{
    void Main() override;
    void ProcessSending();

    TCPConnection m_tcpConnection;
    IpAddress     m_remoteIp;
    IpAddress     m_ipLocal;
};

See also OSAPIThread

Receiving TCP data using blocking sockets in thread's main method

In tcpconnectionthread.cpp file

#include "tcpconnectionthread.h"

// Implementation of the main thread function inherited from OSAPIThread.
void TCPConnectionThread::Main()
{
  // Simplest example:
  try
  {
    CDPMessage("%s started....\\n", OSAPIThread::Name());
    // initialiser TCP her...

    m_ipLocal = (unsigned int)INADDR_ANY;
    m_ipLocal.SetPort(5444);
    m_ipLocal.SetSubnetMask( "255.255.255.0" );

    TCPConnection tcpListen;
    tcpListen.OpenSocket();         // Preferably use OpenSocket() and Listen outside while loop
    tcpListen.Listen(m_ipLocal);    // if not required to reinitialize for each block received

    const int bufferSize = 256;
    char buffer[bufferSize];

    // This code will wait for an incoming connection,
    // and receive up to bufferSize-1 bytes of data
    while(!Stopped())
    {
      TCPConnection tcpIncoming;    // This object will receive the incoming connection
      try
      {
        tcpListen.WaitForIncomingConnection(tcpIncoming);
        while (tcpIncoming.IsConnected() && !Stopped())
        {
          int length = bufferSize-1;
          tcpIncoming.Read(buffer, length);
          CDPMessage("%s: Received the following data:%.*s\\n", OSAPIThread::Name(), length, buffer);
        } // end while
      }
      catch (TCPException& except)
      {
        // NOTE: To prevent the thread from exiting if the remote side closes the connection,
        //       exceptions must be caught somewhere inside the while (!Stopped()) loop.
        CDPMessage("%s::Main(): Exception: %s\\n", OSAPIThread::Name(), except.GetMessage());
      }

      try
      {
        tcpIncoming.ShutDown();
      }
      catch (...)
      {
        // Shouldn't care too much about this
      }
      tcpIncoming.CloseSocket();
    } // end while (!Stopped())

    CDPMessage("%s stopped....\\n",OSAPIThread::Name());

    tcpListen.ShutDown();
    tcpListen.CloseSocket();
  }
  catch (TCPException& except)
  {
    CDPMessage("%s::Main(): TCPException: %s\\n", OSAPIThread::Name(), except.GetMessage());
  }
  catch(...)
  {
    CDPMessage("MyTCPReceiver: Critical exception In Main() function caught. Check code.\\n");
  }
}

Sending TCP data using a non-blocking socket

void TCPConnectionThread::ProcessSending()
{
    if (!m_tcpConnection.IsSocketWriteReady(0))
    {
        try
        {
            // This should preferably be done in Configure() and filled with data from xml file:
            m_remoteIp = "127.0.0.1";
            m_remoteIp.SetSubnetMask("255.255.255.0");
            m_remoteIp.SetPort(5444);

            // Should probably check if connect is already in progress, but this is a simle example...
            m_tcpConnection.OpenSocket();
            m_tcpConnection.SetBlockingMode(false);   // Important if sending from a periodic function to prevent Send() from blocking
            m_tcpConnection.ConnectTo( (unsigned int)INADDR_ANY, m_remoteIp);
        }
        catch (TCPException& except)
        {
            // Print debug message if debug level for this component >= 3. This message
            // will probably be printet every run when destination is not available.
            if (DebugLevel(DEBUGLEVEL_EXTENDED+1))
              CDPMessage("%s: Exception during send, Code 0x%08x: %s\n", OSAPIThread::Name(), except.GetErrorCode(), except.GetMessage());
        }
    }

    const int bufferSize = 10;
    static char data[bufferSize];
    static char todaysCharacter = 'a';
    todaysCharacter = 'a' + ((++todaysCharacter-'a')% 26);
    for (int i=0; i<bufferSize-1; i++)
        data[i] = todaysCharacter;   // Fill buffer with changing data
    data[9] = 0;

    int length = bufferSize;
    if (m_tcpConnection.IsSocketWriteReady(0))
    {
        try
        {
            m_tcpConnection.Send(data, length);
            if (length != bufferSize)
            CDPMessage("%s: Hmmm...Not all data was sent...\n", OSAPIThread::Name());
        }
        catch (TCPException& except)
        {
            // Only print message if Debug>=2 for this component
            if (DebugLevel(DEBUGLEVEL_EXTENDED))
            CDPMessage("%s: Exception during send: %s\n", OSAPIThread::Name(), except.GetMessage());
        }
    }
}

Member Function Documentation

TCPConnection::TCPConnection()

Constructs an instance of TCPConnection

TCPConnection::TCPConnection(const TCPConnection &oldConnection)

Copy constructor.

[virtual] TCPConnection::~TCPConnection()

Destroys the instance

int TCPConnection::CloseSocket()

Closes the TCP socket.

int TCPConnection::ConnectTo(IpAddress ipAddressLocal, IpAddress ipAddressRemote)

Connects to a remote port.

void TCPConnection::EnableReuse(bool bReuse)

Enables reuse of socket.

[virtual] unsigned int TCPConnection::GetInterfaceNo()

Returns which interface number this socket receives/sends packets from/to.

IpAddress &TCPConnection::GetLocalAddress() const

Gets address information of local computer.

Note: It is the reference that is returned, so be aware of the lifetime of the TCPConnection when using the IpAddress.

unsigned int TCPConnection::GetNrBytesPending() const

Returns the number of bytes waiting in the input buffer.

IpAddress &TCPConnection::GetRemoteAddress() const

Gets address information of remote computer.

Note: It is the reference that is returned, so be aware of the lifetime of the TCPConnection when using the IpAddress.

SOCKET TCPConnection::GetSocket() const

Returns TCP socket.

[virtual] int TCPConnection::GetTCPmaxTransferUnitBody()

Returns the TCP packets maximum size.

Negative valueThere will be no splitting in smaller TCP packets.
Positive valueTCP packets larger than this limit, will be split into this size.
0Should never be returned.

bool TCPConnection::IsConnected() const

Returns true if the connection is ready to send or receive.

bool TCPConnection::IsSocketError() const

Determines if socket has error.

bool TCPConnection::IsSocketReadReady(int nTimeoutMs) const

Determines if socket can be read from. Returns false if not.

Use GetNrBytesPending() to check bytes pending.

bool TCPConnection::IsSocketWriteReady(int nTimeoutMs) const

Determines if socket can be written to. Returns false if not.

void TCPConnection::Listen(IpAddress ipAddressLocal)

Listens for incoming connections on a port.

Note: A listening socket is never "connected". IsConnected() will always return false for a listening socket.

bool TCPConnection::MulticastJoin(IpAddress &multicastGroup, IpAddress &localInterface)

Joins a multicast group.

bool TCPConnection::MulticastLeave(IpAddress &multicastGroup, IpAddress &localInterface)

Leaves a multicast group.

int TCPConnection::OpenSocket()

Opens the TCP socket.

By default uses TCP packet maximum size as 4096 bytes. SetTCPmaxTransferUnitBody() must be called after OpenSocket() if another value is used for the socket.

See also SetTCPmaxTransferUnitBody.

void TCPConnection::Read(char *pData, int &length)

Reads incoming data into buffer given my caller.

Parameter pDataPointer to a caller-supplied buffer to be filled with data.
Parameter lengthMax size of buffer and receives the number of bytes read into the buffer.

int TCPConnection::Send(const char *pData, int &length)

Sends data over a connected socket.

Parameter pDataPointer to the buffer to send.
Parameter lengthMax size of buffer and receives the number of bytes read into the buffer.

void TCPConnection::SetAsCloseToRealTimeAsPossible()

Sets socket options to improve real-time performance.

void TCPConnection::SetBlockingMode(bool bBlocking)

Sets the socket to blocking or non-blocking mode.

void TCPConnection::SetBlockingMode(SOCKET specSocket, bool bBlocking)

Sets the socket to blocking or non-blocking mode for specified socket.

bool TCPConnection::SetMulticastTTL(int timeToLive)

Sets timeToLive for multicast (i.e. number of network hops).

void TCPConnection::SetRemoteAddress(IpAddress &remoteIpAddress)

Sets address information of remote computer.

int TCPConnection::SetSocket(SOCKET newSocket, bool isConnected = true, sockaddr *localAddress = NULL)

Sets the TCP socket (copy the socket) using localAddress parameter.

Parameter newSocket (SOCKET)The new socket to bind this TCPConnection to.
Parameter isConnected (bool)Indicates if the socket is bound and connected. Typically after an accept() the socket is already connected to the remote host, and bIsConnected should be set to true.
Parameter localAddress (sockaddr*)The ipaddress for the local host for current TCPConnection. This parameter has type struct sockaddr * for historical reasons. Use type struct sockaddr_in * instead.

int TCPConnection::SetSocket(SOCKET newSocket, IpAddress &localAddress, bool isConnected = true)

Sets the TCP socket (copy the socket) using localAddress as local address parameter.

Parameter newSocket (SOCKET)The new socket to bind this TCPConnection to.
Parameter localAddress (IpAddress&)The ipaddress for the local host for current TCPConnection.
Parameter isConnected (bool)Indicate if the socket is bind and connected. Typically after an accept() the socket is already connected to the remote host, and bIsConnected should be set to true.

[virtual] void TCPConnection::SetTCPmaxTransferUnitBody(int newTCPmaxTransferUnitBody)

Sets the value of TCP packet maximum size

Negative valueThere will be no splitting in smaller TCP packets.
Positive valueTCP packets larger than this limit will be split into this size. Will minimum become size CDP_TCP_MIN_TRANSFER_UNIT_BODY.
0m_iTCPMaxTransferUnitBody will be set to the "global" value returned by EthernetManager::GetInstance()->GetCDPtcpMaxTransferUnitBody().

See also OpenSocket().

void TCPConnection::ShutDown()

Gracefully shuts down a connection. Should be called before CloseSocket().

int TCPConnection::WaitForIncomingConnection(TCPConnection &newConnection) const

Waits for incoming connection on a port. Returns the newly created socket descriptor.

TCPConnection &TCPConnection::operator=(const TCPConnection &oldConnection)

Assignment operator

The content of this document is confidential information not to be published without the consent of CDP Technologies AS.

CDP Technologies AS, www.cdpstudio.com

Get started with CDP Studio today

Let us help you take your great ideas and turn them into the products your customer will love.

Try CDP Studio for free
Why CDP Studio?

CDP Technologies AS
Hundsværgata 8,
P.O. Box 144
6001 Ålesund, Norway

Tel: +47 990 80 900
E-mail: info@cdptech.com

Company

About CDP

Contact us

Services

Partners

Blog

Developers

Get started

User manuals

Support

Document download

Release notes

Follow CDP

  • LinkedIn
  • YouTube
  • GitHub

    © Copyright 2022 CDP Technologies. Privacy and cookie policy.

    Return to top