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

TCP Server and Client example for Linux

Aim

An example to show how to do TCP communication. Support Linux only now.


Source



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

#include "TCPCast.h"
#include "Logger.h"

std::string serverIP = "192.168.1.208";
short serverPort = 7788;
void ServerWorker()
{
    std::vector<char> sendData;
    std::vector<char> recvData;
    TCPCast tcpServer;
    if (tcpServer.InitComponent(serverIP, serverPort, false) == TCPCast::TCPStatus::SUCCESS)
    {
        int count = 0;
        sendData.resize(4);
        recvData.resize(4);
        int clientHandle = tcpServer.Accept(); // waiting for client
        while (true)
        {
            memcpy(&sendData[0], &count, sizeof(int));
            TCPCast::TCPStatus retStatus = tcpServer.ServerSend(clientHandle, &sendData[0], sizeof(int));
            if (retStatus == TCPCast::TCPStatus::SUCCESS)
            {
                LOGMSG_MSG_C("Send success! count: %d\n", count);
            }
            else
            {
                LOGMSG_ERR_C("Send fail!\n");
            }
            count++;

            int byteRecv = 0;
            retStatus = tcpServer.ServerRecv(clientHandle, recvData, byteRecv);
            if (retStatus == TCPCast::TCPStatus::SUCCESS && byteRecv > 0)
            {
                int countRecv = -1;
                memcpy(&countRecv, &recvData[0], sizeof(int));
                LOGMSG_MSG_C("Received count: %d byteRecv: %d\n", countRecv, byteRecv);
            }
        }
    }
    else
    {
        LOGMSG_ERR_C("Cannot InitComponent\n");
    }
}
void ClientWorker()
{
    std::vector<char> sendData;
    std::vector<char> recvData;
    TCPCast tcpClient;
    if (tcpClient.InitComponent(serverIP, 0, true) == TCPCast::TCPStatus::SUCCESS)
    {
        sendData.resize(4);
        recvData.resize(4);
        if (tcpClient.Connect(serverIP, serverPort) == TCPCast::TCPStatus::SUCCESS)
        {
            int count = 2000;
            while (true)
            {
                int byteRecv = 0;
                TCPCast::TCPStatus retStatus = tcpClient.ClientRecv(recvData, byteRecv);
                if (retStatus == TCPCast::TCPStatus::SUCCESS && byteRecv > 0)
                {
                    int countRecv;
                    memcpy(&countRecv, &recvData[0], sizeof(int));
                    LOGMSG_MSG_C("Received count: %d\n", countRecv);
                }

                memcpy(&sendData[0], &count, sizeof(int));
                retStatus = tcpClient.ClientSend(&sendData[0], sizeof(int));
                if (retStatus == TCPCast::TCPStatus::SUCCESS)
                {
                    LOGMSG_MSG_C("Send success! count: %d\n", count);
                }
                else
                {
                    LOGMSG_ERR_C("Send fail!\n");
                }
                count++;
                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(10));
    return 0;
}

Output

$ ./src/TCPServerClient
20200502_104308_399 [MSG]                   TCPCast::                   Accept:   121, 20204,Received client 192.168.1.208:36946
20200502_104308_400 [MSG]              ServerWorker:    28, 20204,Send success! count: 0
20200502_104308_400 [MSG]              ClientWorker:    71, 20206,Received count: 0
20200502_104308_400 [MSG]              ClientWorker:    78, 20206,Send success! count: 2000
20200502_104308_400 [MSG]              ServerWorker:    42, 20204,Received count: 2000 byteRecv: 4
20200502_104308_400 [MSG]              ServerWorker:    28, 20204,Send success! count: 1
20200502_104309_400 [MSG]              ClientWorker:    71, 20206,Received count: 1
20200502_104309_400 [MSG]              ClientWorker:    78, 20206,Send success! count: 2001
20200502_104309_400 [MSG]              ServerWorker:    42, 20204,Received count: 2001 byteRecv: 4
20200502_104309_400 [MSG]              ServerWorker:    28, 20204,Send success! count: 2

Tools Example

Aim

This example is used to show tools example.

Source



#include <iostream>
#include <vector>

#include "Tools.h"

void IsNumberExample()
{
    std::cout << std::endl;
    std::cout << __FUNCTION__ << "-------------------" << std::endl;
    std::cout << Utility::IsNumber("9900") << std::endl;
    std::cout << Utility::IsNumber("99x00") << std::endl;
    std::cout << Utility::IsNumber("99.00") << std::endl;
    std::cout << Utility::IsNumber("99:00") << std::endl;
}
void SplitStringExample()
{
    std::cout << std::endl;
    std::cout << __FUNCTION__ << "-------------------" << std::endl;
    auto parts = Utility::SplitString("abd,cd,sfd,e", ',');
    for (const auto& part : parts)
    {
        std::cout << part << std::endl;
    }
}
void IsBigEndianExample()
{
    std::cout << std::endl;
    std::cout << __FUNCTION__ << "-------------------" << std::endl;
    std::cout << Utility::IsBigEndian() << std::endl;
}
void ReadFileToArrayExample()
{
    std::cout << std::endl;
    std::cout << __FUNCTION__ << "-------------------" << std::endl;
    std::vector<unsigned char> tempData;
    try
    {
        int readSize = Utility::ReadFileToArray("testing.txt", tempData);
        std::cout << "Read Size: " << readSize << std::endl;
    }
    catch (const std::string& err)
    {
        std::cout << err << std::endl;
    }
}
void ReplaceSubstringExample()
{
    std::cout << std::endl;
    std::cout << __FUNCTION__ << "-------------------" << std::endl;
    std::string strInput = "apple is orange and it is not an apple";
    Utility::ReplaceSubstring(strInput, "apple", "orange");
    std::cout << strInput << std::endl;
}
void ReplaceAllSubstringExample()
{
    std::cout << std::endl;
    std::cout << __FUNCTION__ << "-------------------" << std::endl;
    std::string strInput = "apple is orange and it is not an apple";
    Utility::ReplaceAllSubstring(strInput, "apple", "orange");
    std::cout << strInput << std::endl;
}
void GetFolderPathExample()
{
    std::cout << std::endl;
    std::cout << __FUNCTION__ << "-------------------" << std::endl;
    std::string strFolderPathLinux = "/Path/To/Your/File.txt";
    std::cout << "Linux example: " << Utility::GetFolderPath(strFolderPathLinux) << std::endl;
    std::string strFolderPathWindows = "C:\\Path\\To\\Your\\File.txt";
    std::cout << "Windows example: " << Utility::GetFolderPath(strFolderPathWindows) << std::endl;
}
void GetFileNameExample()
{
    std::cout << std::endl;
    std::cout << __FUNCTION__ << "-------------------" << std::endl;
    std::string strFolderPathLinux = "/Path/To/Your/File.txt";
    std::cout << "Linux example: " << Utility::GetFileName(strFolderPathLinux) << std::endl;
    std::string strFolderPathWindows = "C:\\Path\\To\\Your\\File.txt";
    std::cout << "Windows example: " << Utility::GetFileName(strFolderPathWindows) << std::endl;
}
void IsDirExistExample()
{
    std::cout << std::endl;
    std::cout << __FUNCTION__ << "-------------------" << std::endl;
    std::cout << "Linux example: " << Utility::IsDirExist("/Path/To/Your/Folder") << std::endl;
    std::cout << "Windows example: " << Utility::IsDirExist("C:\\Path\\To\\Your\\Folder") << std::endl;
}
void MakePathExample()
{
    std::cout << std::endl;
    std::cout << __FUNCTION__ << "-------------------" << std::endl;
    std::cout << "Create Path on linx: " << Utility::MakePath("./tempFolder") << std::endl;
}
int main(int argc, char *argv[])
{
    IsNumberExample();
    SplitStringExample();
    IsBigEndianExample();
    ReadFileToArrayExample();
    ReplaceSubstringExample();
    ReplaceAllSubstringExample();
    GetFolderPathExample();
    GetFileNameExample();
    IsDirExistExample();
    MakePathExample();
    return 0;
}

Output

$ ./src/Tools 

IsNumberExample-------------------
1
0
1
0

SplitStringExample-------------------
abd
cd
sfd
e

IsBigEndianExample-------------------
0

ReadFileToArrayExample-------------------
Read Size: 60

ReplaceSubstringExample-------------------
orange is orange and it is not an apple

ReplaceAllSubstringExample-------------------
orange is orange and it is not an orange

GetFolderPathExample-------------------
Linux example: /Path/To/Your
Windows example: C:\Path\To\Your

GetFileNameExample-------------------
Linux example: File.txt
Windows example: File.txt

IsDirExistExample-------------------
Linux example: 0
Windows example: 0

MakePathExample-------------------
Create Path on linx: 1