Example: comms_socket_example

Example output:

[Server] Started
[00:27:20.8565|DEBUG|CServerTCPSocket] [CServerTCPSocket] Listening at 127.0.0.1:15000
[00:27:20.8566|DEBUG|CServerTCPSocket] [CServerTCPSocket::accept] Waiting incoming connections
[Client] Connecting
[Client] Connected. Waiting for a message...
[00:27:20.8766|DEBUG|CServerTCPSocket] [CServerTCPSocket::accept] Incoming connection accepted
[00:27:20.8767|DEBUG|CServerTCPSocket] [CServerTCPSocket::accept] Connection accepted from 127.0.0.1:40794
[Server] Connection accepted
[Client] Message received OK!:
  MSG Type: 16
  MSG Length: 119 bytes
[Client] Parsing payload...
[Client] Received payload: [1.000000 2.000000 3.000000 11.459156 22.918312 34.377468]
[Client] tx payload: [1.000000 2.000000 3.000000 11.459156 22.918312 34.377468]
[Client] Done!!
[Client] Finish

Contents of comms_socket_example/SocketsTest_impl.cpp :

/* +------------------------------------------------------------------------+
   |                     Mobile Robot Programming Toolkit (MRPT)            |
   |                          https://www.mrpt.org/                         |
   |                                                                        |
   | Copyright (c) 2005-2024, Individual contributors, see AUTHORS file     |
   | See: https://www.mrpt.org/Authors - All rights reserved.               |
   | Released under BSD License. See: https://www.mrpt.org/License          |
   +------------------------------------------------------------------------+ */

#include <mrpt/comms/CClientTCPSocket.h>
#include <mrpt/comms/CServerTCPSocket.h>
#include <mrpt/poses/CPose3D.h>
#include <mrpt/serialization/CMessage.h>
#include <mrpt/system/scheduler.h>  // changeCurrentThreadPriority()

#include <chrono>
#include <cstdio>  // printf()
#include <iostream>
#include <thread>

bool sockets_test_passed_ok = false;

// Test payload:
const mrpt::poses::CPose3D p_tx(1.0, 2.0, 3.0, 0.2, 0.4, 0.6);

using mrpt::serialization::CMessage;

void thread_server()
{
  using namespace mrpt::comms;
  using namespace std;

  try
  {
#ifdef SOCKET_TEST_VERBOSE
    printf("[Server] Started\n");
#endif

    CServerTCPSocket server(
        15000, "127.0.0.1", 10,
#ifdef SOCKET_TEST_VERBOSE
        mrpt::system::LVL_DEBUG
#else
        mrpt::system::LVL_ERROR
#endif
    );
    std::unique_ptr<CClientTCPSocket> client = server.accept(40000);

    if (client)
    {
#ifdef SOCKET_TEST_VERBOSE
      printf("[Server] Connection accepted\n");
#endif
      // Send a message with the payload:
      CMessage msg;
      msg.type = 0x10;
      msg.serializeObject(&p_tx);

      client->sendMessage(msg);

      std::this_thread::sleep_for(2000ms);
    }

#ifdef SOCKET_TEST_VERBOSE
    printf("[Server] Finish\n");
#endif
  }
  catch (const std::exception& e)
  {
    cerr << e.what() << endl;
  }
  catch (...)
  {
    printf("[thread_server] Runtime error!\n");
  }
}

void thread_client()
{
  using namespace mrpt::comms;
  using namespace std;

  mrpt::system::changeCurrentThreadPriority(mrpt::system::tpLow);

  try
  {
    CClientTCPSocket sock;

#ifdef SOCKET_TEST_VERBOSE
    printf("[Client] Connecting\n");
#endif

    sock.connect("127.0.0.1", 15000);

#ifdef SOCKET_TEST_VERBOSE
    printf("[Client] Connected. Waiting for a message...\n");
#endif
    // cout << "pending: " << sock.getReadPendingBytes() << endl;
    // std::this_thread::sleep_for(500ms);
    // cout << "pending: " << sock.getReadPendingBytes() << endl;

    CMessage msg;
    bool ok = sock.receiveMessage(msg, 10000, 10000);

    if (!ok)
    {
      printf("[Client] Error receiving message!!\n");
    }
    else
    {
#ifdef SOCKET_TEST_VERBOSE
      printf("[Client] Message received OK!:\n");
      printf("  MSG Type: %i\n", msg.type);
      printf("  MSG Length: %u bytes\n", (unsigned int)msg.content.size());
      printf("[Client] Parsing payload...\n");
#endif
      mrpt::poses::CPose3D p_rx;
      msg.deserializeIntoExistingObject(&p_rx);

#ifdef SOCKET_TEST_VERBOSE
      printf("[Client] Received payload: %s\n", p_rx.asString().c_str());
      printf("[Client] tx payload: %s\n", p_tx.asString().c_str());
      printf("[Client] Done!!\n");
#endif

      sockets_test_passed_ok = (p_rx == p_tx);
    }

#ifdef SOCKET_TEST_VERBOSE
    printf("[Client] Finish\n");
#endif
  }
  catch (const std::exception& e)
  {
    cerr << e.what() << endl;
  }
  catch (...)
  {
    cerr << "[thread_client] Runtime error!" << endl;
  }
}

// ------------------------------------------------------
//              SocketsTest
// ------------------------------------------------------
void SocketsTest()
{
  using namespace std::chrono_literals;

  std::thread(thread_server).detach();
  std::this_thread::sleep_for(20ms);

  std::thread t2(thread_client);
  std::this_thread::sleep_for(200ms);
  t2.join();
}

C++ example source code:

/* +------------------------------------------------------------------------+
   |                     Mobile Robot Programming Toolkit (MRPT)            |
   |                          https://www.mrpt.org/                         |
   |                                                                        |
   | Copyright (c) 2005-2024, Individual contributors, see AUTHORS file     |
   | See: https://www.mrpt.org/Authors - All rights reserved.               |
   | Released under BSD License. See: https://www.mrpt.org/License          |
   +------------------------------------------------------------------------+ */

#define SOCKET_TEST_VERBOSE
#include <iostream>

#include "SocketsTest_impl.cpp"

// ------------------------------------------------------
//                      MAIN
// ------------------------------------------------------
int main()
{
  try
  {
    SocketsTest();
    return 0;
  }
  catch (const std::exception& e)
  {
    std::cerr << "MRPT exception caught: " << e.what() << std::endl;
    return -1;
  }
  catch (...)
  {
    std::cerr << "Untyped exception!!";
    return -1;
  }
}