TCPConnection Class
The TCPConnection class represents a Transmission Control Protocol (TCP) connection. More...
Header: | #include <OSAPI/Network/TCPConnection.h> |
Inherited By: |
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 value | There will be no splitting in smaller TCP packets. |
Positive value | TCP packets larger than this limit, will be split into this size. |
0 | Should 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 pData | Pointer to a caller-supplied buffer to be filled with data. |
Parameter length | Max 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 pData | Pointer to the buffer to send. |
Parameter length | Max 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 value | There will be no splitting in smaller TCP packets. |
Positive value | TCP packets larger than this limit will be split into this size. Will minimum become size CDP_TCP_MIN_TRANSFER_UNIT_BODY. |
0 | m_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
Get started with CDP Studio today
Let us help you take your great ideas and turn them into the products your customer will love.