A Windows network monitor built with Flask + pydivert (backend) and React + Recharts (frontend).
Shows real-time per-process traffic — upload/download rates, totals, and a live chart — similar to the Windows Task Manager network tab.
- Per-process download / upload rate and cumulative totals
- Live Recharts line chart (last 60 seconds)
- Sortable process table (by rate, PID, name, connections)
- Kill process (with protection of critical system processes)
- Real packet-level capture via WinDivert (pydivert) — not disk I/O counters
server/
server.py Flask app + API routes
requirements.txt
network/
__init__.py
models.py Dataclasses
connection_monitor.py psutil — connections + flow-to-PID table (Thread 1)
traffic_monitor.py pydivert — packet capture + byte counters (Thread 2)
network_manager.py Orchestrator — merges data, history buffer
src/
services/networkService.ts API calls
utils/formatters.ts formatBytes / formatBytesPerSecond
components/
NetworkMonitor/ Main container + polling (1 s interval)
NetworkSummary/ Download / Upload / Totals cards
NetworkChart/ Recharts real-time line chart
ProcessNetworkTable/ Sortable per-process table
core/interfaces/NetworkTypes.ts TypeScript types
| Package | Purpose |
|---|---|
flask |
REST API |
flask-cors |
CORS for React dev server |
psutil |
Connection list + process info |
pydivert |
WinDivert binding — real network packet capture |
| Package | Purpose |
|---|---|
recharts |
Real-time line chart |
pydivert ships with the WinDivert DLLs.
The server must be run as Administrator so WinDivert can load its kernel driver.
# Inside the server/ directory
pip install -r requirements.txt# Project root
npm installOpen PowerShell as Administrator then:
cd server
python server.pyThe server starts on http://localhost:5001.
If you start without admin privileges the server still runs but traffic monitoring is disabled. The frontend will display a yellow warning banner.
npm run devOpen http://localhost:5173.
| Method | Path | Description |
|---|---|---|
| GET | /api/connections |
Processes + stats + timestamp (main polling endpoint) |
| GET | /api/network/stats |
Global upload/download rates and totals |
| GET | /api/network/history |
Up to 120 historical rate samples |
| GET | /api/process/<pid> |
Per-process details |
| DELETE | /api/kill/<pid> |
Terminate a process |
-
ConnectionMonitor (Thread 1) calls
psutil.net_connections()every 2 s and builds two lookup tables:(local_ip, local_port, remote_ip, remote_port) → PID(precise)(local_ip, local_port) → PID(fallback)
-
TrafficMonitor (Thread 2) opens a WinDivert handle with filter
"tcp or udp".
For every captured packet it:- Extracts
(src_addr, src_port, dst_addr, dst_port, size)— no payload is stored - Determines direction:
is_outbound → upload,is_inbound → download - Looks up the owning PID from the connection table; unattributable packets go to
pid=-1 - Increments per-PID byte counters
- Reinserts the packet immediately (network is never disrupted)
- Extracts
-
A rate thread fires every second:
rate = (current_bytes − prev_bytes) / elapsed_seconds -
NetworkManager merges both sources by PID and maintains a 120-point history deque.
Start the server as Administrator and watch the console for:
[TrafficMonitor] WinDivert capture started.
If you see a warning like "requires Administrator privileges" in the browser, restart the server from an elevated prompt.
-
Only PID, process name, IP, port, protocol, direction, and byte counts are stored.
-
Packet payloads, HTTP headers, cookies, and credentials are never read or stored.
-
The kill endpoint refuses to terminate PIDs 0/4 or named system processes (csrss, lsass, etc.).
-
🐍 Flask – RESTful API backend
-
⚛️ React – Interactive frontend UI
-
📦 psutil +
netstat– For fetching system-level network and process info -
🌐 Fetch API – For communication between frontend and backend
/backend └── app.py # Flask app con 3 endpoints /frontend └── src/ └── App.jsx # UI con tabla, filtros y acciones