This project implements a simple server-client application using Boost.Asio for asynchronous network communication. The server can accept multiple clients, and each client sends data to the server. The server broadcasts received data to all clients, and clients print the received data.
Prerequisites C++17 or later
Boost Libraries (specifically boost_system, boost_thread, and boost_asio)
Install Boost libraries:
- Update the package list:
sudo apt update
- Install Boost libraries:
sudo apt install libboost-all-dev
- Install Homebrew (if not already installed):
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
- Install Boost librarues using Homebrew:
brew install boost
- Download Boost:
Visit the Boost download page and download the latest version of Boost. Extract Boost:
- Extract the downloaded Boost archive to a directory (e.g., C:\local\boost_1_76_0).
- Build Boost (optional, if you need specific libraries):
Open a Command Prompt and navigate to the Boost directory. Run the following commands:
bootstrap.bat
.\b2
Please note that the default installation path will be usr/local/
Please note that : /usr/local/include & /usr/local/lib in the below needs to be adjusted if you have a specific install path for Boost
Clone the repository:
git clone <repository-url>
cd <repository-directory>
Compile/Build the Server and Client files:
- For the server application:
g++ -std=c++17 -g src/Server/mainServer.cpp src/Server/PositionServer.cpp -I include -I /usr/local/include -L /usr/local/lib -o build/PositionServer -lboost_system -lboost_thread -lpthread
- For the Client application:
g++ -std=c++17 -g src/Client/mainClient.cpp src/Client/PositionClient.cpp -I include -I /usr/local/include -L /usr/local/lib -o build/PositionClient -lboost_system -lboost_thread -lpthread
Clone the repository:
git clone <repository-url>
cd <repository-directory>
Compile/Build the Server and Client files:
- For the server application:
g++ -std=c++17 -g src\\Server\\mainServer.cpp src\\Server\\PositionServer.cpp -I include -I C:\\local\\boost_1_76_0 -L C:\\local\\boost_1_76_0\\stage\\lib -o build\\PositionServer.exe -lboost_system -lboost_thread -lws2_32
- For the Client application:
g++ -std=c++17 -g src\\Client\\mainClient.cpp src\\Client\\PositionClient.cpp -I include -I C:\\local\\boost_1_76_0 -L C:\\local\\boost_1_76_0\\stage\\lib -o build\\PositionClient.exe -lboost_system -lboost_thread -lws2_32
Note: The -lws2_32 linker option is required on Windows for networking
2. Run the following commands to initialize the Server applicion (Please note that the server will now be running)
./positionServer false # Linux/macOS
positionServer.exe false # Windows
Please note that the client application has two command line arguments
- The executable file (.exe)
- (Boolean) is whether the user would like debug Log files to be printed, for the test application it is set to false, but if you would like a more detailed view of the interaction please set this to true
For the Client application:
Run the following commands in shell (The more teminals openend in this manner the better !! ie more clients)
./positionClient 127.0.0.1 12345 BTCUSDT.BKN 1200 false 1201 0 # Linux/macOS
./positionClient.exe 127.0.0.1 12345 BTCUSDT.BKN 1200 false 1201 0 # Windows
Please note that the above application has 8 fields which need to be fed into the command line
- The executable file (.exe)
- The host address (127....)
- The Server Address that the client needs to access (12345)
- The unique client ID+exchange (BTCUSDT.BN)
- How often the clients position will upate (in milliseconds) (800: for testing I Please limit this to less 2000 or extend server lifetime in mainServer.cpp)
- Boolean value if we would like the debug logs to be printed, default is false (false)
- The local port number to ensure the socket IDs are unique (int)
- If you want the client thread to assume function 1 or 2 in the clientMain.cpp (used for testing)
5. Repeat steps 3 and 4 in different terminals with different client names, this will ensure maximal interaction between server and client
The clients will send their ID to the server upon connection.
The server will reject connections if a client with the same ID already exists.
The clients send random position data to the server, which the server broadcasts to all clients.
PositionServer.h and PositionServer.cpp: Server implementation (Located in src/Server).
PositionClient.h and PositionClient.cpp: Client implementation (Located in src/Client).
Common.h: Common definitions and global variables.
mainServer.cpp: Main file to start the server(Located in src/Server).
mainClient.cpp: Main file to start a client(Located in src/Client).
./positionServer false # Linux/macOS
./positionClient 127.0.0.1 12345 BTCUSDT.BKN 1200 false 1201 0 # Linux/macOS
./positionClient 127.0.0.1 12345 BTCUSDT.BN 1200 false 1202 0 # Linux/macOS
./positionClient 127.0.0.1 12345 BTCUSDT.KRKN 1200 false 1203 0 # Linux/macOS
PositionServer constructed and acceptor initialized on port 12345
Starting PositionServer on port 12345
Starting worker threads
Running io_context
As an example, I am going to keep the server running for 60 seconds (self set)
This can be altered for testing OR the server can be closed prematurely by pushing CTRL C...
Accepted connection from: 127.0.0.1:64573
Received message from client: BTCUSDT.BKN, net position: 123.45, timestamp: 2024-Jun-24 09:56:13
Accepted connection from: 127.0.0.1:64574
Received message from client: BTCUSDT.BN, net position: 123.45, timestamp: 2024-Jun-24 09:56:14
Sending BroadCast to: 127.0.0.1:64574
Sent broadcast: Client position upon joining to Client BTCUSDT.BN:| BTCUSDT.BKN, Net Position: 95.9567, Timestamp of client: 2024-Jun-24 09:56:14
Client BTCUSDT.BKN closed connection.
Client 127.0.0.1 disconnected and removed from the set.
Client BTCUSDT.BKN disconnected and removed from the set.
Accepted connection from: 127.0.0.1:64575
Received message from client: BTCUSDT.BKN, net position: 123.45, timestamp: 2024-Jun-24 09:56:28
Sending BroadCast to: 127.0.0.1:64575
Sent broadcast: Client position upon joining to Client BTCUSDT.BKN:| BTCUSDT.BN, Net Position: 88.8986, Timestamp of client: 2024-Jun-24 09:56:27
Server stopped.
Stopping server...
Server resources cleaned up and stopped.
Received broadcast on ClientID: BTCUSDT.BN| Update for Client: BTCUSDT.HB, Net Position: 71.4657, Timestamp of update: 2024-Jun-19 18:05:44
Received broadcast on ClientID: BTCUSDT.BN| Update for Client: BTCUSDT.KRKN, Net Position: 76.9948, Timestamp of update: 2024-Jun-19 18:05:44
Received broadcast on ClientID: BTCUSDT.BN| Update for Client: BTCUSDT.HB, Net Position: 78.4795, Timestamp of update: 2024-Jun-19 18:05:44
Received broadcast on ClientID: BTCUSDT.BN| Update for Client: BTCUSDT.KRKN, Net Position: 99.3953, Timestamp of update: 2024-Jun-19 18:05:45
Received broadcast on ClientID: BTCUSDT.BN| Update for Client: BTCUSDT.KRKN, Net Position: 78.8712, Timestamp of update: 2024-Jun-19 18:05:45
Received broadcast on ClientID: BTCUSDT.BN| Update for Client: BTCUSDT.HB, Net Position: 83.1269, Timestamp of update: 2024-Jun-19 18:05:45
.......
Received broadcast on ClientID: BTCUSDT.BN| Update for Client: BTCUSDT.HB, Net Position: 80.3377, Timestamp of update: 2024-Jun-19 18:05:54
Received broadcast on ClientID: BTCUSDT.BN| Update for Client: BTCUSDT.HB, Net Position: 71.4785, Timestamp of update: 2024-Jun-19 18:05:55
Received broadcast on ClientID: BTCUSDT.BN| Update for Client: BTCUSDT.HB, Net Position: 80.6918, Timestamp of update: 2024-Jun-19 18:05:55
Received broadcast on ClientID: BTCUSDT.BN| Update for Client: BTCUSDT.HB, Net Position: 77.865, Timestamp of update: 2024-Jun-19 18:05:56
Successfully joined client thread...
Position client has been destructed...
In high-frequency trading (HFT), multiple trading systems or exchanges interact with each other at extremely high speeds to capitalize on market inefficiencies. To effectively simulate these interactions, it is essential to represent each exchange as an independent entity that can operate concurrently and communicate with a central server. This is why we run multiple clients in different terminals.
-
Isolation of Processes: Each terminal represents an independent client process, simulating a separate exchange or trading system. This isolation ensures that the behavior of one client does not directly interfere with others, providing a more realistic simulation of a distributed trading environment.
-
Concurrent Interactions: Running multiple clients concurrently allows us to simulate real-world scenarios where multiple exchanges interact with a central server simultaneously. This concurrency is crucial for testing the performance and robustness of the server under different conditions.
-
Independent Data Streams: Each client can send and receive its own data stream, representing different market data and orders. This diversity in data helps test the server's ability to handle various types of information and ensures that the system can process and broadcast updates accurately and efficiently.
-
Realistic Testing Environment: In HFT, exchanges operate independently but interact frequently. By running multiple clients, we can test the server's ability to handle rapid data exchange and ensure that it maintains consistency and accuracy across all connected clients.
TCP ensures all clients have a consistent view of positions by guaranteeing reliable and error-free data delivery. This keeps all strategies on the same page.
TCP delivers data in the exact order it was sent, which is crucial in HFT where the sequence of updates matters. No risk of scrambled data.
TCP handles dropped connections and packet loss with retransmissions and flow control, ensuring no information is lost even if there are network issues.
In short, TCP is the best fit for ensuring our HFT desk's strategies stay accurate and synchronized.