A lightweight, cross-platform NTRIP client for Linux, macOS, and Windows that:
- Connects to an NTRIP caster to receive RTCM correction data
- Reads GGA NMEA messages from a GPS receiver on a serial port
- Sends GGA position to the NTRIP caster for VRS (Virtual Reference Station) support
- Forwards RTCM corrections to the GPS receiver
- Runs a TCP server to forward serial data to multiple clients
# Using make
make
# Or directly with g++
g++ -std=c++17 -O2 -o ntrip_client ntrip_client.cpp -pthreadUsing Visual Studio Developer Command Prompt:
cl /EHsc /std:c++17 /O2 ntrip_client.cpp ws2_32.libUsing MinGW-w64:
g++ -std=c++17 -O2 -o ntrip_client.exe ntrip_client.cpp -lws2_32Create a config.json file:
{
"ntrip_host": "truertk.pointonenav.com",
"ntrip_port": 2101,
"ntrip_mountpoint": "POALRIS",
"ntrip_user": "your_username",
"ntrip_password": "your_password",
"serial_port": "/dev/ttyUSB0",
"serial_baud": 115200,
"tcp_port": 5000,
"gga_interval_sec": 10
}Note: On Windows, use "serial_port": "COM3" (or appropriate COM port).
| Field | Required | Default | Description |
|---|---|---|---|
ntrip_host |
Yes | - | NTRIP caster hostname |
ntrip_port |
No | 2101 | NTRIP caster port |
ntrip_mountpoint |
Yes | - | Mountpoint name |
ntrip_user |
No | - | Username for authentication |
ntrip_password |
No | - | Password for authentication |
serial_port |
Yes | - | Serial port path (e.g., /dev/ttyUSB0, COM3) |
serial_baud |
No | 9600 | Baud rate (4800, 9600, 19200, 38400, 57600, 115200, 230400) |
tcp_port |
No | 0 | TCP server port for forwarding serial data (0 = disabled) |
gga_interval_sec |
No | 10 | Interval for sending GGA to caster |
When tcp_port is set, the client starts a TCP server that forwards all serial data to connected clients. Multiple clients can connect simultaneously.
Example: Connect with netcat
nc localhost 5000Example: Connect with Python
There is a full featured example in the python folder which connects to the TCP port and generates a live webpage with position and signal strength.
python python/gps_plotter.py ./ntrip_client config.jsonPress Ctrl+C to stop.
On Linux, you may need to add your user to the dialout group:
sudo usermod -a -G dialout $USER
# Log out and back in for changes to take effectOn macOS, serial ports are typically accessible without additional configuration.
Linux:
- USB serial:
/dev/ttyUSB0,/dev/ttyUSB1 - ACM devices:
/dev/ttyACM0,/dev/ttyACM1
macOS:
- USB serial:
/dev/tty.usbserial-*,/dev/tty.usbmodem*
Windows:
- COM ports:
COM1,COM3,COM10, etc.
List available ports:
# Linux
ls /dev/tty*
# macOS
ls /dev/tty.*
# Windows (PowerShell)
[System.IO.Ports.SerialPort]::GetPortNames()
# Windows (Command Prompt)
mode- Opens the serial port and connects to the GPS receiver
- Connects to the NTRIP caster and authenticates
- Reads NMEA data from the serial port, parsing GGA messages
- Sends GGA messages to the NTRIP caster periodically (for VRS)
- Receives RTCM correction data from the caster
- Writes RTCM data to the serial port (to the GPS receiver)
- Optionally forwards all serial data to a TCP socket
None! Uses only standard C++17 and platform APIs:
- Linux/macOS: POSIX (termios, sockets)
- Windows: Win32 API (serial), Winsock2 (sockets)
The project includes a comprehensive test suite with unit tests and integration tests.
# Run all tests
make test
# Run only unit tests
make test-unit
# Run only integration tests
make test-integration
# Run integration test with custom duration (default 15 seconds)
cd test && ./run_tests.sh integration 30The test suite includes:
-
Unit Tests
- GGA message extraction
- Base64 encoding for authentication
- JSON configuration parsing
-
Integration Test
- Mock NTRIP server that validates connections and receives GGA
- GPS simulator that generates NMEA sentences on a PTY
- Full end-to-end data flow verification
You can also run the test components manually:
# Build test binaries
make test-binaries
# Terminal 1: Start mock NTRIP server
./build/mock_ntrip_server -p 2101 -m TEST -u user -P pass
# Terminal 2: Start GPS simulator (note the PTY path it prints)
./build/gps_simulator
# Terminal 3: Create test config and run client
# (use PTY path from GPS simulator output as serial_port)
./ntrip_client test_config.jsonThe systemd/ directory contains everything needed to run the NTRIP client as a system service on Linux.
# Build the client
make
# Install the service (uses config.json from current directory)
sudo ./systemd/install-service.sh
# Or specify a custom config file
sudo ./systemd/install-service.sh /path/to/my-config.json-
Create a dedicated user:
sudo useradd -r -s /usr/sbin/nologin -G dialout ntrip
-
Install the binary:
sudo cp ntrip_client /usr/local/bin/ sudo chmod 755 /usr/local/bin/ntrip_client
-
Install the configuration:
sudo mkdir -p /etc/ntrip sudo cp config.json /etc/ntrip/ sudo chmod 640 /etc/ntrip/config.json sudo chown root:ntrip /etc/ntrip/config.json
-
Install the service file:
sudo cp systemd/ntrip-client.service /etc/systemd/system/ sudo systemctl daemon-reload
-
Enable and start the service:
sudo systemctl enable ntrip-client sudo systemctl start ntrip-client
# Check service status
sudo systemctl status ntrip-client
# View logs (live)
sudo journalctl -u ntrip-client -f
# View recent logs
sudo journalctl -u ntrip-client --since "1 hour ago"
# Restart after config change
sudo systemctl restart ntrip-client
# Stop the service
sudo systemctl stop ntrip-client
# Disable auto-start
sudo systemctl disable ntrip-clientWhen running as a service, the configuration file is located at:
/etc/ntrip/config.json
Edit it with:
sudo nano /etc/ntrip/config.json
sudo systemctl restart ntrip-clientThe service runs as the ntrip user which is added to the dialout group. This provides access to serial ports. If you're using a USB-serial adapter, make sure it appears as /dev/ttyUSB* or /dev/ttyACM*.
If your device uses a different path, edit the service file:
sudo systemctl edit ntrip-clientAdd:
[Service]
DeviceAllow=/dev/your-device rwService won't start:
# Check for errors
sudo journalctl -u ntrip-client -e
# Test config manually
sudo -u ntrip /usr/local/bin/ntrip_client /etc/ntrip/config.jsonPermission denied on serial port:
# Check device permissions
ls -la /dev/ttyUSB0
# Verify ntrip user is in dialout group
groups ntrip
# Add to dialout group if needed
sudo usermod -a -G dialout ntrip
sudo systemctl restart ntrip-clientService keeps restarting:
- Check logs for connection errors
- Verify NTRIP server credentials
- Check network connectivity
sudo ./systemd/uninstall-service.shOr manually:
sudo systemctl stop ntrip-client
sudo systemctl disable ntrip-client
sudo rm /etc/systemd/system/ntrip-client.service
sudo systemctl daemon-reload
sudo rm /usr/local/bin/ntrip_client
sudo rm -rf /etc/ntrip
sudo userdel ntripMIT License - feel free to use and modify.