Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

nqts — network quality testing tool

A small, fast, dependency-free iperf-style network quality tester. A single binary runs as either a server or a client and measures:

  • Throughput — TCP download / upload, single or parallel streams (Mbps, per-second intervals)
  • Latency / RTT — UDP echo (min / avg / max / stddev)
  • Jitter — RFC 3550 interarrival jitter
  • Packet loss — derived from UDP sequence numbers

It is written in portable C and runs on Linux (gcc) and Windows x64 (MSVC / Visual Studio). There is no TLS and no authentication by design — run it on trusted networks or behind a firewall (see Security).

Building

Linux

make                      # builds ./nqts
sudo make install         # installs to /usr/local/bin
sudo make install-service # also installs + reloads the systemd unit

Requirements: gcc/cc, make, libpthread, libm (all standard on Debian).

Windows (Visual Studio / MSVC)

Open a Developer Command Prompt for VS (so cl.exe and the Windows SDK are on PATH), then either:

build-windows.bat

or:

nmake /f Makefile.win

Both produce nqts.exe and link ws2_32.lib.

Usage

nqts is one binary with two modes: a server that waits for tests, and a client that connects to a server and runs them. Start the server on the machine you want to test to, then run the client from the machine you want to test from.

Quick start

# On the server machine:
nqts server

# On the client machine (replace with the server's IP/hostname):
nqts client 192.0.2.10 --mode download --time 10

Server

nqts server [--bind ADDR] [--port N] [--udp-port N]
Option Default Description
--bind ADDR all Restrict to one interface (e.g. --bind 10.0.0.5)
--port N 5210 TCP control + throughput port
--udp-port N =--port UDP port for ping / jitter-loss tests
-h, --help Show help

The server runs in the foreground and prints a line such as nqts server listening on TCP *:5210, UDP *:5210 (no TLS/auth). It handles many clients concurrently (one thread per connection). Stop it with Ctrl+C (graceful shutdown). To run it unattended, see Running as a service.

Open the firewall so clients can reach both the TCP and UDP port:

# Example with ufw (Debian/Ubuntu); adjust the port if you changed --port
sudo ufw allow 5210/tcp
sudo ufw allow 5210/udp

Client

nqts client <host> --mode <download|upload|ping|udp> [options]

<host> is the server's IP address or hostname. The client connects to the TCP --port, runs the selected test, prints per-second progress (for throughput tests) and a final summary.

Client modes

Mode Measures Transport
download throughput, server → client TCP
upload throughput, client → server TCP
ping round-trip latency + probe loss UDP echo
udp jitter + packet loss (uplink) UDP

Client options

Option Applies to Default Description
--mode all download download | upload | ping | udp
--port N all 5210 server TCP control/data port
--time N download/upload/udp 10 test duration, seconds
--streams N download/upload 1 parallel TCP streams (1–64)
--size N all mode block / datagram size in bytes
--rate N udp 1000 datagrams per second
--count N ping 10 number of probes
--interval N ping 1000 inter-probe interval, ms

Examples

# --- on the server ---
nqts server --bind 0.0.0.0 --port 5210

# --- on the client (192.0.2.10 is the server) ---

# 10-second download with 4 parallel streams
nqts client 192.0.2.10 --mode download --time 10 --streams 4

# upload test
nqts client 192.0.2.10 --mode upload --time 10

# 20 latency probes, 200ms apart
nqts client 192.0.2.10 --mode ping --count 20 --interval 200

# 5-second UDP jitter/loss test at 5000 pps, 1200-byte datagrams
nqts client 192.0.2.10 --mode udp --time 5 --rate 5000 --size 1200

Example client output for a download test:

Connecting 4 stream(s) to 192.0.2.10:5210 for download test (10 s)
  [ 1 s]   942.10 Mbps
  [ 2 s]   948.73 Mbps
  ...
------------------------------------------------
Download: 1180.42 MB in 10.00 s = 944.34 Mbps (4 streams)

Ports

Purpose Default Override
TCP control + throughput 5210 --port
UDP ping + jitter/loss 5210 --udp-port

The client always connects to the TCP --port first; the server then tells it which UDP port to use for ping/udp tests.

Running as a service (Linux)

On Linux the server can run unattended via systemd. The provided systemd/nqts-server.service is a hardened unit (DynamicUser, NoNewPrivileges, ProtectSystem=strict, restricted syscalls/capabilities), so it runs as a transient unprivileged user with no manual account setup.

Install

From the repo directory:

sudo make install-service

This installs the nqts binary to /usr/local/bin/, copies the unit to /etc/systemd/system/nqts-server.service, and runs systemctl daemon-reload. Then enable and start it (now and on every boot):

sudo systemctl enable --now nqts-server

Verify

systemctl status nqts-server
journalctl -u nqts-server -f      # live logs

You should see a listening on TCP *:5210, UDP *:5210 line. Remember to open the firewall for both the TCP and UDP port (see Server).

Change ports or bind address

Edit the ExecStart line in /etc/systemd/system/nqts-server.service, e.g.:

ExecStart=/usr/local/bin/nqts server --bind 10.0.0.5 --port 6000 --udp-port 6000

Then reload and restart:

sudo systemctl daemon-reload
sudo systemctl restart nqts-server

Stop / remove

sudo systemctl stop nqts-server        # stop now
sudo systemctl disable nqts-server     # don't start on boot
sudo rm /etc/systemd/system/nqts-server.service
sudo systemctl daemon-reload

The service auto-restarts on failure (Restart=on-failure).

Running on Windows

nqts.exe runs as a normal console program in either mode. To stop a running server, press Ctrl+C (handled gracefully). Running it as a Windows Service is not included in this version.

Security

There is no encryption and no authentication. A reachable server will run throughput and UDP tests for anyone who can connect, which can consume significant bandwidth. Therefore:

  • Bind to a specific interface with --bind (e.g. --bind 10.0.0.5) instead of all interfaces.
  • Restrict access with a firewall (open the TCP/UDP port only to trusted hosts).
  • Do not expose it directly to the public internet.

How it works

The client opens a TCP control connection and sends a fixed binary request (magic NQTS, version, test type, duration, sizes, stream count). The request and all control messages are serialized field-by-field in network byte order (no packed structs), so the wire format is identical across compilers and architectures.

  • TCP throughput streams payload blocks for the requested duration; the receiver counts bytes. Parallel streams open additional TCP connections and are multiplexed on the client with select() (no threads). Upload byte totals are reported authoritatively by the server.
  • UDP ping sends timestamped datagrams the server echoes; the client computes RTT from its monotonic clock.
  • UDP jitter/loss sends sequenced, timestamped datagrams at a target rate; the server tracks sequence gaps (loss) and RFC 3550 interarrival jitter and returns the summary over the control channel.

All OS-specific code (Winsock2 vs POSIX sockets, monotonic time, threads, shutdown signals) is isolated in src/platform.{h,c}.

Layout

Makefile            Linux build
Makefile.win        Windows (MSVC nmake) build
build-windows.bat   Windows (MSVC) one-shot build
src/
  protocol.h        wire format + serialization helpers
  platform.{h,c}    OS-compatibility layer
  common.{h,c}      sockets, robust I/O, statistics, formatting
  server.c          server mode
  client.c          client mode
  nqts.c            entry point / mode dispatch
systemd/
  nqts-server.service

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages