Pages - Menu

標籤

AWS (1) bash (1) Boost (2) C (2) CMake (2) Concurrency_Programming (3) CPP (37) Database (2) DNS (1) Docker (4) Docker-Compose (1) ELK (1) emacs (4) gcp (1) gdrive (1) git (1) gitbash (2) gitlab (1) kvm (4) Linux (5) MT4 (4) MT5 (4) Multicast (2) MySQL (2) Nijatrader8 (1) OpenCV (1) Python (4) QT5 (1) R (1) rdp (3) screenshot (1) ssh (3) Tabnine (1) TCP (1) TensorFlow (1) Tools (12) Ubuntu_1904 (11) Ubuntu_20_04 (5) UDP (1) VS2010 (1) VS2015 (1) VS2019 (1) WebServer (1) Win10 (1) winmerge (1) WSL (1) xrdp (1)

搜尋此網誌

2020年11月15日星期日

Use winmerge in git bash

 .gitconfig

location

  •  C:\Users\<name>\.gitconfig

.gitconfig

[diff]
       tool = winmerge
       prompt = false
[difftool "winmerge"]
       path = C:/Program Files/WinMerge/winmergeu.exe
	   cmd = \"C:/Program Files/WinMerge/winmergeu.exe\" /e /u /wl /dl "$LOCAL" /dr "$REMOTE" "$LOCAL" "$REMOTE"
[merge]
       tool = winmerge
       prompt = false
[mergetool "winmerge"]
       path = C:/Program Files/WinMerge/winmergeu.exe
       cmd = \"C:/Program Files/WinMerge/winmergeu.exe\" /e /u /wl /dl "$LOCAL" /dr "$REMOTE" "$LOCAL" "$REMOTE" -o "$MERGED"
       trustExitCode = true
       keepBackup = false
[diff]
       tool = meld
       prompt = false
[difftool "meld"]
       path = C:/Program Files (x86)/Meld/Meld.exe
	   cmd = \"C:/Program Files (x86)/Meld/Meld.exe\" "$LOCAL" "$MERGED" "$REMOTE" --output "$MERGED"
[merge]
       tool = meld
       prompt = false
[mergetool "meld"]
       path = C:/Program Files (x86)/Meld/Meld.exe
       cmd = \"C:/Program Files (x86)/Meld/Meld.exe\" "$LOCAL" "$MERGED" "$REMOTE" --output "$MERGED"
       trustExitCode = true
       keepBackup = false
[user]
	email = sflee1112@gmail.com
	name = SulfredLee

2020年11月6日星期五

How cmake find package works

 Aim

Here are some examples showing how to use cmake find packet.

 Learn from

Here

Examples - use default modules

ALSA library

You can install the library first.

$ sudo apt-get install libasound2

You can put the following code into CMakeLists.txt.

# Handle ALSA / ASound libraries
find_package(ALSA)
if (ALSA_FOUND)
  message (STATUS "Info - Found ALSA library: ${ALSA_LIBRARY}")
  message (STATUS "Info - Found ALSA include: ${ALSA_INCLUDE_DIR}")
else (ALSA_FOUND)
  message (FATAL_ERROR "Info - ALSA is not found")
endif (ALSA_FOUND)

How can I know which variables I can use?

 

2020年10月23日星期五

Install xrdp on ubuntu

 Ubuntu 20.04

Install and use (Basic)

  • Install xrdp by

$ sudo apt-get install xrdp

  • Logout, since you cannot remote login while the session is begin used.
  • Connect from other PC, for example:

 

  • DONE

If not working

  • By default Xrdp uses the /etc/ssl/private/ssl-cert-snakeoil.key file which is readable only by users that are members of the “ssl-cert” group. Learn From
  • Add to group ssl-start.
$ sudo adduser xrdp ssl-start

Change close lip behavior



  • Restart service to activate your change
 $ sudo systemctl systemd-logind.service

2020年10月3日星期六

Core dump file in ubuntu

 Aim

When running c++ application, we would like to get the core dump when the application is crashed. How to get those files under linux?

Learn from

Link

Steps

Add to ~/.bashrc 

ulimit -c unlimited

Add to /etc/sysctl.conf

kernel.core_pattern = core.%e.%p.%t

Run command:

$ sudo sysctl --system

Ubuntu KVM guest os network

 On Ubuntu 20.04

You can use the default setting first:


If the guest OS cannot connect to internet, you may try the host nic and bridge it:


If that is not okay, you may need to create a new network source. The easiest way is to install VMWare workstation or Virtual box. They will create the needed network configuration for their VMs. Now you can use the network source created by them. Here is an example:




Ubuntu KVM OpenGL

 On Ubuntu 20.04

Setup

This acceleration can be use only locally. You have to disable the spice server first.


Then you can start your VM through graphical console

Ubuntu KVM multiple monitors

 On Ubuntu 20.04

Learn From

 Steps

Add one more Video QXL 


Set Display Spice and open port for example 5907


 Start VM without using virt-manager graphical console

Finally, you need to use remote-viewer and open up the guest firewall:

You may try directly remote-view the instance first, if not work, you may add the firewall steps

$ sudo apt-get install firewalld
$ sudo firewall-cmd --permanent --add-service=vdsm
$ sudo firewall-cmd --reload
$ remote-viewer spice://localhost:5907

2020年10月2日星期五

Screenshot tools

 Windows

 Install Greenshot

Ubuntu

Install Flameshot

Steps

Install applications

sudo apt-get install flameshot

Disable default shortcut

 


Add shortcut


Update Filename




2020年5月7日星期四

Concurrency message queue in C++

Aim

In this post, I would like to see how to build a concurrency message queue in C++ that is fast. The fastest message queue I can make at this moment is the Lock Free Ring Buffer message queue. There is more details in the result part.

Source

Testing method

There is a speed test framework implemented in SpeedTest class. No matter what type of message queue we are using, a number of message will be pushed into the MsgQ by multiple number of threads at the same time there are the same number of threads reading message from that MsgQ.

We then have a timer to count the total time that is needed to process all the messages.

We have different type of message queue:

Lock Free MsgQ

  1. MsgQLockFree with Ring Buffer

Using Linux Concurrency library

  1. MsgQOneLock with Ring Buffer
  2. MsgQTwoLock with Ring Buffer
  3. MsgQOneLock with LinkList 
  4. MsgQTwoLock with LinkList

Using C++ standard library

  1. MsgQOneLock with Ring Buffer
  2. MsgQTwoLock with Ring Buffer
  3. MsgQOneLock with LinkList 
  4. MsgQTwoLock with LinkList
As one can see that there are currently 3 types of message queue:
  1. Lock free
  2. One lock
  3. Two lock
We would like to see their difference in speed.

More on Queue

Lock Free

I learn this from here. I made a simplified version. This is a concurrency message queue but only support 2 threads. 1 thread is pushing message and 1 thread is getting message.
In this message queue we have no mutex lock. There are 2 pointers, one is pointing to the next empty slot(Tail) and the other is pointing to the next ready message slot(Head). The length of the message queue is a power of 2. Since there is no mutex lock, __sync_val_compare_and_swap() is used.

One Lock

The other type of message queue is a queue that is using one lock.
There is one mutex protecting the Head and Tail pointers. More than 2 threads can be supported.

Two Lock

There are two mutex protecting the Head and Tail pointers. More than 2 threads can be supported.

The Test

Hardware

  • Intel(R) Core(TM) i5-6500 CPU @ 3.20GHz
  • 4 core
  • 4 threads
  • Ubuntu 20.04 LTS

Test Info

  • 300000 messages
  • Threads
    • 1 in, 1 out
    • 2 in , 2 out
    • 4 in, 4 out
    • 10 in, 10 out
  • 5 total tests and get the average time spend

Result

MsgQ TypeThread INThread OUTTotal MessageTotal testTime spend Msec
Lock Free11300000546
One Lock113000005115
Two Lock113000005102.5

The above grape comparing 1 thread in and 1 thread out case. The lock free message queue is the fastest one. This is expected.


Thread IOTotal MessageTotal testMsec One LockMsec Two Lock
Two3000005122135.5
Four3000005133.5119
Ten3000005150.5124
The above graph shows that the speed of MsgQ with 2 locks is better. We have 2 threads IN and OUT, 4 threads and 10 threads in these tests.

Raw Result

MsgQLockFree_Linux11300000546
MsgQLockFree_LinkList_Std113000005100
MsgStackLockFree_LinkList_Std113000005296
MsgStackLockFree_LinkList_Std223000005406
MsgStackLockFree_LinkList_Std443000005806
MsgStackLockFree_LinkList_Std10103000005568
MsgQOneLock_RingBuf_Linux113000005111
MsgQOneLock_RingBuf_Linux223000005109
MsgQOneLock_RingBuf_Linux443000005135
MsgQOneLock_RingBuf_Linux10103000005186
MsgQTwoLock_RingBuf_Linux11300000586
MsgQTwoLock_RingBuf_Linux223000005135
MsgQTwoLock_RingBuf_Linux443000005132
MsgQTwoLock_RingBuf_Linux10103000005128
MsgQOneLock_RingBuf_Std113000005119
MsgQOneLock_RingBuf_Std223000005137
MsgQOneLock_RingBuf_Std443000005106
MsgQOneLock_RingBuf_Std10103000005115
MsgQTwoLock_RingBuf_Std113000005100
MsgQTwoLock_RingBuf_Std223000005136
MsgQTwoLock_RingBuf_Std443000005106
MsgQTwoLock_RingBuf_Std10103000005120
MsgQOneLock_LinkList_Linux113000005229
MsgQOneLock_LinkList_Linux223000005201
MsgQOneLock_LinkList_Linux443000005195
MsgQOneLock_LinkList_Linux10103000005197
MsgQTwoLock_LinkList_Linux113000005179
MsgQTwoLock_LinkList_Linux223000005268
MsgQTwoLock_LinkList_Linux443000005225
MsgQTwoLock_LinkList_Linux10103000005213
MsgQOneLock_LinkList_Std113000005250
MsgQOneLock_LinkList_Std223000005189
MsgQOneLock_LinkList_Std443000005209
MsgQOneLock_LinkList_Std10103000005223
MsgQTwoLock_LinkList_Std113000005166
MsgQTwoLock_LinkList_Std223000005267
MsgQTwoLock_LinkList_Std443000005212
MsgQTwoLock_LinkList_Std10103000005219
MsgQOneLock_Queue_Linux113000005203
MsgQOneLock_Queue_Linux223000005158
MsgQOneLock_Queue_Linux443000005152
MsgQOneLock_Queue_Linux10103000005172
MsgQOneLock_Queue_Std113000005178
MsgQOneLock_Queue_Std223000005151
MsgQOneLock_Queue_Std443000005150
MsgQOneLock_Queue_Std10103000005154

2020年5月4日星期一

List of time complexity for standard data structure

CPP


Container Insert Append Access
Vector, String O(n) Back: O(1) or O(n) O(1)
Dequeue O(n) Front or Back: O(1) O(1)
List O(1)or O(n) O(1) O(1) or O(n)
Set, Map O(logN) - O(logN)
unordered_set, unordered_map O(1) or O(n) - O(1) or O(n)

Python

Python List ~ CPP List
Python Dict ~ CPP unordered_map
Python dequeue ~ CPP Dequeue

Big O cheat sheet

link

2020年5月3日星期日

PcapReplayer

Aim

This is an application build for replay .pcal files for network debugging.

This application can:
  • Run on Ubuntu
  • Run on Windows
  • Replay a list of pcap files, drag and drop
  • Schedule a replay event
  • Replay at a customized speed, change speed anytime
  • Pause in the middle of the replay process
  • Know current replay status
  • Select different interface
  • Loop replay

Source


Features

Run on Ubuntu

Download the binaries from here.
  • $ export LD_LIBRARY_PATH=/usr/local/yourLib/lib
  • $ sudo ./bin/PcapReplayer

Run on Windows

Download the binaries from here.

Replay a list of pcap files, Drag and Drop

Schedule a reply report


Replay at a customized speed, change speed anytime

Know the current replay status

Select different interface

Loop Replay

You can replay the same list again and again.

2020年5月2日星期六

Inherit example in C

Aim

In this example we simulate inheritance in C.

Source



#include <iostream>
#include "allFood.h"

int main(int argc, char *argv[])
{
    food* pApple = createApple();
    ((apple*)pApple)->nNumber = 10;
    pApple->printName("001");
    fprintf(stdout, "We have %d apples.\n", ((apple*)pApple)->nNumber);
    food* pOrange = createOrange();
    pOrange->printName("002");
    return 0;
}

Output

$ ./src/Inherit_C 
I am an apple 001
We have 10 apples.
I am an orange 002

Example to simulate class in C.

Aim

In this example, we simulate the class concept in C. We separate public and private parts in the MsgQ_C.c source file. The message Q is a linked list with 2 mutex locks so that the congestion is reduced.

Source



#include <iostream>
#include <thread>
#include <string.h>
#include <unistd.h>

#include "MsgQ_C.h"
#include "Logger.h"

MsgQ_C* queue = createMsgQ_C();

void thread001Fun()
{
    int i = 0;
    while (true)
    {
        char* string = new char[1024];
        sprintf(string, "number %03d", i++);
        pushMsgQ_C((void**)&string, queue);
        usleep(500000); // sleep 0.5 sec
    }
}

void thread002Fun()
{
    int i = 1000;
    while (true)
    {
        char* string = new char[1024];
        sprintf(string, "number %03d", i++);
        pushMsgQ_C((void**)&string, queue);
        usleep(1000000); // sleep 1 sec
    }
}

int main(int argc, char* argv[])
{
    std::thread thread001(thread001Fun);
    std::thread thread002(thread002Fun);
    while (true)
    {
        char* string;
        getMsgQ_C((void**)&string, queue);
        LOGMSG_MSG_C("%s\n", string);
        delete string;
    }

    freeMsgQ_C(queue);
    return 0;
}

Output

$ ./src/HiddenStruct_C 
20200502_195819_176 [MSG]                      main:    43, 13323,number 1000
20200502_195819_176 [MSG]                      main:    43, 13323,number 000
20200502_195819_676 [MSG]                      main:    43, 13323,number 001
20200502_195820_176 [MSG]                      main:    43, 13323,number 1001

Multicast non stop sending setup. Primary and Secondary server.

Aim

This is an example to show how to use multicast to deliver a "non stop" sending server. This class is supported Linux.

Logic

In this example, we first have 2 servers. There is a way for them to select the primary server and send out the multicast data. On the above picture, Server 2 is the primary.

After several seconds in our example, we will turn off Server 2. They will then select the primary server again. There is a chance for Server 2 to become primary again but mostly Server 1 will take the role faster.

Source



#include <iostream>
#include <string.h>
#include <thread>
#include <chrono>
#include <atomic>

#include "MCastArbitrator.h"
#include "Logger.h"
#include "LinuxThread.h"

// usgae: ./MCastArbitrator

std::string MCastAddress = "225.1.32.28";
short MCastPort = 6000;
std::string SenderIP = "192.168.1.208";
class Sender : public LinuxThread
{
public:
    Sender() { m_running = true; }
    ~Sender() { stopThread(); m_running = false; joinThread(); }

    bool InitComponent(int instance) { m_instance = instance; startThread(); return true; }
    void ChangeStatusForTest() { MCArbi.ChangeStatus(MCastArbitrator::MCArbiStatus::SECONDARY); }
private:
    // override
    void *Main()
    {
        std::vector<char> sendData;

        if (MCArbi.InitComponent(SenderIP, MCastPort, 32, m_instance) == MCastArbitrator::MCArbiStatus::SUCCESS)
        {
            MCArbi.JoinGroup(MCastAddress);
            sendData.resize(4);
            int count = 0;
            while(m_running.load())
            {
                memcpy(&sendData[0], &count, sizeof(int));
                MCastArbitrator::MCArbiStatus retStatus = MCArbi.Send(&sendData[0], sizeof(int));
                if (retStatus == MCastArbitrator::MCArbiStatus::SUCCESS)
                {
                    LOGMSG_MSG("Send success! count: %d instance: %d\n", count, m_instance);
                }
                else
                {
                    // LOGMSG_ERR("Send fail! instance: %d\n", m_instance);
                }
                count++;
                usleep(1000000); // 1 sec
            }
        }
        return NULL;
    }
public:
    int m_instance;
private:
    std::atomic<bool> m_running;
    MCastArbitrator MCArbi;
};
int main(int argc, char *argv[])
{
    Sender *sender001 = new Sender(); sender001->InitComponent(1);
    std::this_thread::sleep_for(std::chrono::seconds(1));
    Sender *sender002 = new Sender(); sender002->InitComponent(2);

    int count = 1;
    int lastDie = 2;
    while (true)
    {
        if (count % 5 == 0)
        {
            if (lastDie == 2)
            {
                sender001->ChangeStatusForTest();
                lastDie = 1;
            }
            else
            {
                sender002->ChangeStatusForTest();
                lastDie = 2;
            }
            count = 0;
        }
        count++;
        std::this_thread::sleep_for(std::chrono::seconds(1));
    }
    return 0;
}

Output

$ ./src/MCastArbitrator 
20200502_183146_131 [MSG]           MCastArbitrator::          SendArbitration:    70,  9136,Start thread
20200502_183146_132 [MSG]           MCastArbitrator::       ReceiveArbitration:   106,  9137,Start thread
20200502_183146_632 [MSG]           MCastArbitrator::SwitchStatus_LongTimeNoUpdate:   211,  9137,IN
20200502_183146_632 [MSG]           MCastArbitrator::              PrintStatus:   174,  9137,Status updated Raise hand
20200502_183146_882 [MSG]           MCastArbitrator::              PrintStatus:   174,  9137,Status updated Primary
20200502_183147_131 [MSG]                    Sender::                     Main:    41,  9135,Send success! count: 1 instance: 1
20200502_183147_132 [MSG]           MCastArbitrator::          SendArbitration:    70,  9139,Start thread
20200502_183147_132 [MSG]           MCastArbitrator::       ReceiveArbitration:   106,  9140,Start thread
20200502_183147_132 [MSG]           MCastArbitrator::              PrintStatus:   174,  9140,Status updated Secondary
20200502_183148_132 [MSG]                    Sender::                     Main:    41,  9135,Send success! count: 2 instance: 1
20200502_183149_132 [MSG]                    Sender::                     Main:    41,  9135,Send success! count: 3 instance: 1
20200502_183150_132 [MSG]                    Sender::                     Main:    41,  9135,Send success! count: 4 instance: 1
20200502_183151_386 [MSG]           MCastArbitrator::SwitchStatus_LongTimeNoUpdate:   211,  9140,IN
20200502_183151_386 [MSG]           MCastArbitrator::              PrintStatus:   174,  9140,Status updated Raise hand
20200502_183151_386 [MSG]           MCastArbitrator::SwitchStatus_LongTimeNoUpdate:   211,  9137,IN
20200502_183151_386 [MSG]           MCastArbitrator::              PrintStatus:   174,  9137,Status updated Raise hand
20200502_183151_634 [MSG]           MCastArbitrator::              PrintStatus:   174,  9137,Status updated Secondary
20200502_183151_634 [MSG]           MCastArbitrator::              PrintStatus:   174,  9140,Status updated Primary
20200502_183152_132 [MSG]                    Sender::                     Main:    41,  9138,Send success! count: 5 instance: 2
20200502_183153_132 [MSG]                    Sender::                     Main:    41,  9138,Send success! count: 6 instance: 2

From the above output example, you can see that the first primary server is instance 1. After a while, we turn off instance 1 and then instance 2 comes up.

2020年5月1日星期五

Multicast sender and receiver example for Linux

Aim

This is an example to show Multicast sender and receiver. This class support on Linux.


Source




#include <iostream>
#include <string.h>
#include <thread>
#include <chrono>

#include "MultiCast.h"
#include "Logger.h"

std::string MCastAddress = "225.1.32.28";
short MCastPort = 6000;
std::string SenderIP = "192.168.1.208";
std::string ReceiverIP = "";
void MCastSender()
{
    std::vector<char> sendData;
    Multicast MCast;

    if (MCast.InitComponent(SenderIP, MCastPort) == Multicast::MCStatus::SUCCESS)
    {
        sendData.resize(4);
        int count = 0;
        while(true)
        {
            memcpy(&sendData[0], &count, sizeof(int));
            Multicast::MCStatus retStatus = MCast.Send(MCastAddress, &sendData[0], sizeof(int));
            if (retStatus == Multicast::MCStatus::SUCCESS)
            {
                LOGMSG_MSG_C("Send success! count: %d\n", count);
            }
            else
            {
                LOGMSG_ERR_C("Send fail!\n");
            }
            count++;
            usleep(1000000); // 1 sec
        }
    }
}
void MCastReceiver()
{
    std::vector<char> receivedData;
    std::string fromAddress;
    short fromPort;
    int byteRecv;
    Multicast MCast;

    if (MCast.InitComponent(ReceiverIP, MCastPort) == Multicast::MCStatus::SUCCESS)
    {
        MCast.JoinGroup(MCastAddress);

        receivedData.resize(1024);
        while(true)
        {
            if (MCast.SelectRead(500, 0) == Multicast::MCStatus::READ) // wait for 500 microsecond
            {
                if (MCast.Recv(receivedData, fromAddress, fromPort, byteRecv) == Multicast::MCStatus::SUCCESS)
                {
                    int count;
                    memcpy(&count, &receivedData[0], sizeof(int));
                    LOGMSG_MSG_C("Received from %s:%u count: %d\n", fromAddress.c_str(), fromPort, count);
                }
            }
        }
    }
}
int main(int argc, char *argv[])
{
    std::thread senderTH(MCastSender);
    senderTH.detach();
    std::this_thread::sleep_for(std::chrono::seconds(1));
    std::thread receiverTH(MCastReceiver);
    receiverTH.detach();

    std::this_thread::sleep_for(std::chrono::seconds(5));
    return 0;
}

Output

$ ./src/MCastSenderReceiver 
20200502_123309_832 [MSG]               MCastSender:    28, 25698,Send success! count: 0
20200502_123310_833 [MSG]               MCastSender:    28, 25698,Send success! count: 1
20200502_123311_833 [MSG]               MCastSender:    28, 25698,Send success! count: 2

UDP server client example for Linux

Aim

This is an example to show UDP server and client example. This class support Linux only.


Source



#include <iostream>
#include <string.h>

#include "UDPCast.h"
#include "Logger.h"

std::string serverIP = "192.168.1.208";
std::string clientIP = "192.168.1.208";
short serverPort = 7788;
short clientPort = 8899;
void ServerWorker()
{
    std::vector<char> sendData;
    std::vector<char> recvData;
    UDPCast udpServer;
    if (udpServer.InitComponent(serverIP, serverPort, false) == UDPCast::UDPStatus::SUCCESS)
    {
        int count = 0;
        sendData.resize(4);
        recvData.resize(4);
        while (true)
        {
            std::string clientAddress;
            short clientPort;
            int byteRecv = 0;
            UDPCast::UDPStatus retStatus = udpServer.Recv(clientAddress, clientPort, recvData, byteRecv);
            if (retStatus == UDPCast::UDPStatus::SUCCESS && byteRecv > 0)
            {
                int countRecv = -1;
                memcpy(&countRecv, &recvData[0], sizeof(int));
                LOGMSG_MSG_C("Received count: %d byteRecv: %d\n", countRecv, byteRecv);
            }

            memcpy(&sendData[0], &count, sizeof(int));
            retStatus = udpServer.Send(clientAddress, clientPort, &sendData[0], sizeof(int));
            if (retStatus == UDPCast::UDPStatus::SUCCESS)
            {
                LOGMSG_MSG_C("Send success! count: %d\n", count);
            }
            else
            {
                LOGMSG_ERR_C("Send fail!\n");
            }
            count++;
        }
    }
    else
    {
        LOGMSG_ERR_C("Cannot InitComponent\n");
    }
}
void ClientWorker()
{
    std::vector<char> sendData;
    std::vector<char> recvData;
    UDPCast udpClient;

    if (udpClient.InitComponent(clientIP, clientPort, true) == UDPCast::UDPStatus::SUCCESS)
    {
        sendData.resize(4);
        recvData.resize(4);
        int count = 2000;
        while (true)
        {
            memcpy(&sendData[0], &count, sizeof(int));
            UDPCast::UDPStatus retStatus = udpClient.Send(serverIP, serverPort, &sendData[0], sizeof(int));
            if (retStatus == UDPCast::UDPStatus::SUCCESS)
            {
                LOGMSG_MSG_C("Send success! count: %d\n", count);
            }
            else
            {
                LOGMSG_ERR_C("Send fail!\n");
            }
            count++;

            int byteRecv = 0;
            retStatus = udpClient.Recv(serverIP, serverPort, recvData, byteRecv);
            if (retStatus == UDPCast::UDPStatus::SUCCESS && byteRecv > 0)
            {
                int countRecv;
                memcpy(&countRecv, &recvData[0], sizeof(int));
                LOGMSG_MSG_C("Received count: %d\n", countRecv);
            }
            usleep(1000000); // 1 sec
        }
    }
}
int main(int argc, char *argv[])
{
    std::thread serverTH(ServerWorker);
    serverTH.detach();
    std::this_thread::sleep_for(std::chrono::seconds(1));
    std::thread clientTH(ClientWorker);
    clientTH.detach();

    std::this_thread::sleep_for(std::chrono::seconds(5));
    return 0;
}

Output

$ ./src/UDPServerClient 
20200502_112401_921 [MSG]              ClientWorker:    69, 22550,Send success! count: 2000
20200502_112401_921 [MSG]              ServerWorker:    31, 22548,Received count: 2000 byteRecv: 4
20200502_112401_921 [MSG]              ServerWorker:    38, 22548,Send success! count: 0
20200502_112401_921 [MSG]              ClientWorker:    83, 22550,Received count: 0
20200502_112402_921 [MSG]              ClientWorker:    69, 22550,Send success! count: 2001
20200502_112402_921 [MSG]              ServerWorker:    31, 22548,Received count: 2001 byteRecv: 4
20200502_112402_922 [MSG]              ServerWorker:    38, 22548,Send success! count: 1
20200502_112402_922 [MSG]              ClientWorker:    83, 22550,Received count: 1