TcpClient C++ library
v1.2.1
Table of contents
- Overview
- Versions
- Library files
- TcpClient class description
- Example
- Build and connect to your project
Overview
TcpClient C++ library provides methods to work with TCP socket as client (connect, close, send data and receive data). TcpClient library is cross-platform and compatible with Windows and Linux OS. The library utilizes C++17 standard and doesn’t have any third-party dependencies. Main file TcpClient.h includes declaration of TcpClient class which provides methods to work with TCP socket as a client.
Versions
Table 1 - Library versions.
Version | Release date | What’s new |
---|---|---|
1.0.0 | 17.05.2023 | First version. |
1.1.0 | 13.10.2023 | - Add local port configuration support. |
1.1.1 | 30.10.2023 | - Fixed local port bind issue. |
1.1.2 | 06.03.2024 | - Documentation updated. |
1.1.3 | 16.04.2024 | - Documentation updated. |
1.1.4 | 22.05.2024 | - Documentation updated. |
1.2.0 | 29.07.2024 | - CMake structure updated. - Implementation code moved to separate folder. |
1.2.1 | 18.11.2024 | - Disable SIGPIPE signal. |
Library files
The library is supplied only by source code. The user is given a set of files in the form of a CMake project (repository). The repository structure is shown below:
CMakeLists.txt ------------- Main CMake file of the library.
src ------------------------ Folder with library source code.
CMakeLists.txt --------- CMake file of the library.
TcpClient.h ------------ Main library header file.
TcpClient.cpp ---------- C++ class definitions file.
TcpClientVersion.h ----- Header file with library version.
TcpClientVersion.h.in -- File for CMake to generate version header.
impl
TcpClientImpl.h ----- Library implementation header file.
TcpClientImpl.cpp --- C++ implementation file.
test ----------------------- Folder for test application.
CMakeLists.txt --------- CMake file of test application.
main.cpp --------------- Source code of test application.
TcpClient class description
Class declaration
TcpClient class declared in TcpClient.h file. Class declaration:
class TcpClient
{
public:
/// Class constructor.
TcpClient();
/// Class destructor.
~TcpClient();
/// Get current class version string.
static std::string getVersion();
/// Connect to server.
bool connect(std::string ip, int serverPort, int timeoutMsec = 100, int clientPort = -1);
/// Get connection status.
bool isConnected();
/// Close connection.
void close();
/// Send data to server.
int send(uint8_t* data, int size);
/// Read data from server.
int read(uint8_t* data, int size);
};
getVersion method
The getVersion() method return string of current class version. Method declaration:
static std::string getVersion();
Method can be used without TcpClient class instance:
std::cout << "TcpClient version: " << cr::clib::TcpClient::getVersion();
Console output:
TcpClient version: 1.2.0
connect method
The connect(…) method initializes TCP connection to server. Method declaration:
bool connect(std::string ip, int serverPort, int timeoutMsec = 100, int clientPort = -1);
Parameter | Value |
---|---|
ip | IP address of TCP server. |
serverPort | TCP server port. Must have values from 0 to 65535. |
timeoutMsec | Wait data timeout. Method sets timeout to TCP socket properties. Timeout determines behavior of read(…) method: method will wait input data maximum timeoutMsec milliseconds and will return negative results if no input data. |
clientPort | TCP client port. Must have values from 0 to 65535. If set to -1 the library will chose port itself. |
Returns: TRUE if connection done or FALSE if not.
read method
The read(…) method designed to read (wait) input data. After receiving input data the method will return control immediately or will return control after timeout (set connect(…) method) if no input data. Method declaration:
int read(uint8_t* data, int size);
Parameter | Value |
---|---|
data | Pointer to data buffer. |
size | Size of data buffer and maximum data size to read from socket. |
Returns: Number of bytes or -1 if no input data or timeout expired (set in open(…) method) or UDP socket not open.
send method
The send(…) sends data. Method declaration:
int send(uint8_t* data, int size);
Parameter | Value |
---|---|
data | Pointer to data buffer. |
size | Size of data to send. |
Returns: Number of bytes sent or -1 if data not sent (no connection or others errors).
isConnected method
The isConnected() method returns TCP connections status. Method declaration:
bool isConnected();
Returns: TRUE if TCP client connected to server or FALSE if not.
close method
The close() method designed to close connection if it open. Method declaration:
void close();
Build and connect to your project
Typical commands to build TcpClient library:
cd TcpClient
mkdir build
cd build
cmake ..
make
If you want connect TcpClient library to your CMake project as source code you can make follow. For example, if your repository has structure:
CMakeLists.txt
src
CMakeList.txt
yourLib.h
yourLib.cpp
Create folder 3rdparty and copy folder of TcpClient repository there. New structure of your repository:
CMakeLists.txt
src
CMakeList.txt
yourLib.h
yourLib.cpp
3rdparty
TcpClient
Create CMakeLists.txt file in 3rdparty folder. CMakeLists.txt should contain:
cmake_minimum_required(VERSION 3.13)
################################################################################
## 3RD-PARTY
## dependencies for the project
################################################################################
project(3rdparty LANGUAGES CXX)
################################################################################
## SETTINGS
## basic 3rd-party settings before use
################################################################################
# To inherit the top-level architecture when the project is used as a submodule.
SET(PARENT ${PARENT}_YOUR_PROJECT_3RDPARTY)
# Disable self-overwriting of parameters inside included subdirectories.
SET(${PARENT}_SUBMODULE_CACHE_OVERWRITE OFF CACHE BOOL "" FORCE)
################################################################################
## CONFIGURATION
## 3rd-party submodules configuration
################################################################################
SET(${PARENT}_SUBMODULE_TCP_CLIENT ON CACHE BOOL "" FORCE)
if (${PARENT}_SUBMODULE_TCP_CLIENT)
SET(${PARENT}_TCP_CLIENT ON CACHE BOOL "" FORCE)
SET(${PARENT}_TCP_CLIENT_TEST OFF CACHE BOOL "" FORCE)
endif()
################################################################################
## INCLUDING SUBDIRECTORIES
## Adding subdirectories according to the 3rd-party configuration
################################################################################
if (${PARENT}_SUBMODULE_TCP_CLIENT)
add_subdirectory(TcpClient)
endif()
File 3rdparty/CMakeLists.txt adds folder TcpClient to your project and excludes test application from compiling (by default test applications and example are excluded from compiling if TcpClient is included as sub-repository). The new structure of your repository:
CMakeLists.txt
src
CMakeList.txt
yourLib.h
yourLib.cpp
3rdparty
CMakeLists.txt
TcpClient
Next you need include folder 3rdparty in main CMakeLists.txt file of your repository. Add string at the end of your main CMakeLists.txt:
add_subdirectory(3rdparty)
Next you have to include TcpClient library in your src/CMakeLists.txt file:
target_link_libraries(${PROJECT_NAME} TcpClient)
Done!
Example
Test application shows how to create TCP client and connect to server. The application trying connect to server after start or trying connect to server if connection disappears.
#include <iostream>
#include <chrono>
#include <ctime>
#include <thread>
#include "TcpClient.h"
int main(void)
{
std::cout << "TcpClient v" << cr::clib::TcpClient::getVersion() << " test" << std::endl;
std::string ip = "";
std::cout << "Set TCP server IP: ";
std::cin >> ip;
int serverPort = 0;
std::cout << "Enter server port: ";
std::cin >> serverPort;
int clientPort = 0;
std::cout << "Enter client port: ";
std::cin >> clientPort;
// Create client and connect to server.
cr::clib::TcpClient client;
while (!client.connect(ip, serverPort, 500, clientPort))
{
std::cout << "Can't connect to server" << std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
continue;
}
// Main loop.
const int numBytes = 128;
uint8_t data[numBytes];
while (true)
{
// Check connection.
if (!client.isConnected())
{
// Connect to CommsManager. 4 msec wait data timeout.
if (!client.connect(ip, serverPort, 500, clientPort))
{
std::cout << "Can't connect to server" << std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
continue;
}
}
// Prepare random data.
for (int i = 0; i < numBytes; ++i)
{
data[i] = (uint8_t)(rand() % 255);
}
// Send data to server.
std::cout << client.send(data, numBytes) << " bytes sent" << std::endl;
// Wait response.
int bytes = client.read(data, numBytes);
// Check result.
if (bytes <= 0)
{
std::cout << "No response from server" << std::endl;
}
else
{
std::cout << bytes << " bytes received" << std::endl;
}
}
return 1;
}