tcpserver_web_logo

TcpServer C++ library

v2.1.0

Table of contents

Overview

The TcpServer C++ library provides methods to work with TCP sockets as a server (wait for connections, close connections, send data, and receive data). The TcpServer library is cross-platform and compatible with Windows and Linux operating systems. The library uses the C++17 standard and doesn’t have any third-party dependencies. The main file TcpServer.h includes the declaration of the TcpServer class, which provides methods to work with TCP sockets as a server. The library has an internal thread to wait for connections from clients. All of the library’s methods are thread-safe, which means it is safe to call them from different threads. The library stores the list of connected clients internally, and this list is updated with the read(…) method.

Versions

Table 1 - Library versions.

Version Release date What’s new
1.0.0 08.06.2023 - First version
1.0.1 13.10.2023 - Connection issues fixed.
1.0.2 11.03.2024 - Client reconnection issue fixed.
- Documentation updated.
1.0.3 16.04.2024 - Documentation updated.
1.0.4 22.05.2024 - Documentation updated.
1.0.5 30.07.2024 - CMake structure updated.
2.0.0 10.09.2024 - New interface.
2.0.1 25.03.2025 - Frequent connection requests issue solved.
- Detection of disconnected client issue for Windows fixed.
2.0.2 14.04.2025 - Fixed read timeout behavior.
2.0.3 26.08.2025 - Improved stability and fixed critical bugs.
2.1.0 30.10.2025 - Added additional configuration to reduce TCP ACK delay.

Library files

The library is supplied as source code only. The user receives 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.
    TcpServer.h ------------ Main library header file.
    TcpServer.cpp ---------- C++ implementation file.
    TcpServerVersion.h ----- Header file with library version.
    TcpServerVersion.h.in -- File for CMake to generate version header.
test ----------------------- Folder for test application.
    CMakeLists.txt --------- CMake file to include test application.
    main.cpp --------------- Source code of test application.

TcpServer class description

Class declaration

The TcpServer class is declared in the TcpServer.h file. Class declaration:

class TcpServer
{
public:

    /// Destructor.
    ~TcpServer();

    /// Method to get string of current library version.
    static std::string getVersion();

    /// Initialize TCP server.
    bool init(int port);

    /// Read data from clients.
    int read(uint8_t* buffer, int size, TcpClientInfo& client, int timeout = 1000);

    /// Send data to a client.
    int send(uint8_t* buffer, int bufferSize, TcpClientInfo client);

    /// Check if client connected.
    bool isConnected(TcpClientInfo client);

    /// Get connected clients.
    std::vector<TcpClientInfo> getClients();

    /// Close TCP socket.
    void close();
};

getVersion method

The getVersion() method returns string of current class version. Method declaration:

static std::string getVersion();

Method can be used without TcpServer class instance:

std::cout << "TcpServer version: " << cr::clib::TcpServer::getVersion();

Console output:

TcpServer version: 2.1.0

init method

The init(…) method is designed to initialize the TCP server. Method declaration:

bool init(int port);
Parameter Value
port TCP port. Must have a value from 0 to 65535.

Returns: TRUE if initialization is successful or FALSE if not.

read method

The read(…) method reads (waits for) input data from a client. After receiving input data, the method will return control immediately, or will return control after a timeout if no input data is received. This method also updates the list of connected clients. Method declaration:

int read(uint8_t* buffer, int size, TcpClientInfo& client, int timeout = 1000);
Parameter Value
buffer Pointer to data buffer.
size Number of bytes to read.
client Reference to TcpClientInfo structure. It will be filled with information about the client that sent the data.
timeout Wait timeout for data in milliseconds. Default value is 1000 ms.

Returns: Number of bytes received or -1 if no input data.

send method

The send(…) method sends data. Method declaration:

int send(uint8_t* buffer, size_t bufferSize, TcpClientInfo client);
Parameter Value
buffer Pointer to data buffer.
bufferSize Size of data to send.
client TcpClientInfo structure with client information.

Returns: Number of bytes sent or -1 if data was not sent.

isConnected method

The isConnected() method returns the client’s connection status. Method declaration:

bool isConnected(TcpClientInfo client);
Parameter Value
client TcpClientInfo structure with client information.

Returns: TRUE if the client is connected to the server or FALSE if not.

getClients method

The getClients() method returns a list of connected clients. This list is updated by the read(…) method. If any client’s connection is lost after invoking read(…), the getClients() method will return a list that includes the disconnected client. Method declaration:

std::vector<TcpClientInfo> getClients();

Returns: List of TcpClientInfo structures with connected client information.

close method

The close() method closes the server if it is open. The method also stops the internal thread that is waiting for incoming client connection requests. Method declaration:

void close();

TcpClientInfo class description

TcpClientInfo structure class declaration

The TcpClientInfo structure contains information about a client. Structure declaration:

struct TcpClientInfo
{
    std::string ip;
    int port;
};
Field Type Description
ip string Client IP address
port int Client port

Build and connect to your project

Typical commands to build the TcpServer library:

cd TcpServer 
mkdir build
cd build
cmake ..
make

If you want to connect the TcpServer library to your CMake project as source code, you can follow these steps. For example, if your repository has the following structure:

CMakeLists.txt
src
    CMakeList.txt
    yourLib.h
    yourLib.cpp

Create a folder named 3rdparty and copy the TcpServer repository folder there. The new structure of your repository:

CMakeLists.txt
src
    CMakeList.txt
    yourLib.h
    yourLib.cpp
3rdparty
    TcpServer

Create a CMakeLists.txt file in the 3rdparty folder. The 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)

################################################################################
## INCLUDING SUBDIRECTORIES
## Adding subdirectories according to the 3rd-party configuration
################################################################################
if (${PARENT}_SUBMODULE_TCP_SERVER)
    add_subdirectory(TcpServer)
endif()

The 3rdparty/CMakeLists.txt file adds the TcpServer folder to your project and excludes the test application from compilation (by default, test applications and examples are excluded from compilation if TcpServer is included as a sub-repository). The new structure of your repository:

CMakeLists.txt
src
    CMakeList.txt
    yourLib.h
    yourLib.cpp
3rdparty
    CMakeLists.txt
    TcpServer

Next, you need to include the 3rdparty folder in the main CMakeLists.txt file of your repository. Add the following line at the end of your main CMakeLists.txt:

add_subdirectory(3rdparty)

Next, you have to include the TcpServer library in your src/CMakeLists.txt file:

target_link_libraries(${PROJECT_NAME} TcpServer)

Done!

Example

This test application shows how to create a TCP server and wait for connections from clients.

#include <iostream>
#include <chrono>
#include <vector>
#include <thread>
#include "TcpServer.h"
#include "TcpServerVersion.h"



int main(void)
{
    std::cout << "TcpServer v" << cr::clib::TcpServer::getVersion() << " test" << std::endl;

    int port = 9909;

    // Init TCP server.
    cr::clib::TcpServer server;
    while(!server.init(port))
    {
        std::cout << "Server not initialized" << std::endl;
        continue;
    }

    const uint32_t bufferSize = 10000;
    uint8_t buffer[bufferSize];

    cr::clib::TcpClientInfo client;

    while(1)
    {
        // Wait for data from client.
        int bytes = server.read(buffer, bufferSize, client);
        if (bytes <= 0)
        {
            std::cout << "No input data" << std::endl;
            std::this_thread::sleep_for(std::chrono::milliseconds(1000));
            continue;
        }

        std::cout << "Received " << bytes << " bytes from client " << client.ip << ":" << client.port << std::endl;

        // Send data back to client.
        int sentBytes = server.send(buffer, bytes, client);
        if (sentBytes <= 0)
        {
            std::cout << "Couldn't send data to client" << std::endl;
        }
    }

    return 0;
}

Table of contents