tcpserver_web_logo

TcpServer C++ library

v2.0.0

Table of contents

Overview

TcpServer C++ library provides methods to work with TCP socket as server (wait connection, close, send data and receive data). TcpServer library is cross-platform and compatible with Windows and Linux OS. The library uses C++17 standard and doesn’t have any third-party dependencies. Main file TcpServer.h includes declaration of TcpServer class which provides methods to work with TCP socket as server. The library has a internal thread to wait connections from clients. The library’s all 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 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.

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.
    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

TcpServer class declared in 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.0.0

init method

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

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

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

read method

The read(…) method reads (wait) input data from client. After receiving input data the method will return control immediately or will return control after timeout if no input data. 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 of client that sent data.
timeout Wait data timeout in milliseconds. Default value is 1000 ms.

Returns: Number of bytes 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 not sent.

isConnected method

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

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

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

getClients method

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

std::vector<TcpClientInfo> getClients();

Returns: List of TcpClientInfo structures with connected clients information.

close method

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

void close();

TcpClientInfo class description

TcpClientInfo structure class declaration

TcpClientInfo structure contains information about 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 TcpServer library:

cd TcpServer 
mkdir build
cd build
cmake ..
make

If you want connect TcpServer 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 TcpServer repository there. New structure of your repository:

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

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_SERVER                      ON  CACHE BOOL "" FORCE)
if (${PARENT}_SUBMODULE_TCP_SERVER)
    SET(${PARENT}_TCP_SERVER                            ON  CACHE BOOL "" FORCE)
    SET(${PARENT}_TCP_SERVER_TEST                       OFF CACHE BOOL "" FORCE)
endif()

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

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

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

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 TcpServer library in your src/CMakeLists.txt file:

target_link_libraries(${PROJECT_NAME} TcpServer)

Done!

Example

Test application shows how to create TCP server and wait connection from client.

#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 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.
        server.send(buffer, bytes, client);
        if (bytes <= 0)
        {
            std::cout << "Couldn't send data to client" << std::endl;
        }
    }

    return 0;
}