The tcp.cc file has been modified to integrate with NS3's OpenGym module, enabling Reinforcement Learning (RL) algorithms to control TCP congestion behavior in real-time. A complete DQN (Deep Q-Network) implementation has been provided in Python.
#include "ns3/opengym-module.h"A new class TcpOpenGymEnv that inherits from OpenGymEnv to implement the OpenGym interface:
-
GetObservationSpace(): Defines a 5-dimensional continuous observation space
- Current Congestion Window (normalized to [0,1])
- Current RTT (normalized)
- Throughput (normalized)
- Packet Loss Rate
- CWND change rate
-
GetActionSpace(): Defines 5 discrete actions
- 0: Decrease sending rate by 50%
- 1: Decrease rate by 25%
- 2: Maintain current rate
- 3: Increase rate by 25%
- 4: Increase rate by 50%
-
GetObservation(): Returns current network state as normalized values
-
GetReward(): Calculates reward based on:
Reward = Throughput - (10 × PacketLossRate) - (2 × RTT)This balances throughput maximization with loss and delay minimization.
-
ExecuteActions(): Processes actions from the RL agent
-
State Tracking Methods:
SetCwnd(): Updates congestion window measurementsSetRtt(): Updates RTT measurementsSetThroughput(): Updates throughput measurementsSetPacketLoss(): Updates packet loss statistics
New parameters for OpenGym control:
bool openGymEnabled = true; // Enable/disable OpenGym
uint32_t openGymPort = 5555; // Communication port
double envStepTime = 0.1; // RL decision interval (seconds)
uint32_t simSeed = 1; // Random seed
double simTime = 50.0; // Simulation durationPtr<TcpOpenGymEnv> openGymEnv = CreateObject<TcpOpenGymEnv>(simSeed, simTime, openGymPort, envStepTime);
openGymEnv->SetOpenGymInterface(OpenGymInterface::Get(openGymPort));Modified congestion window traces to update the OpenGym environment:
if (openGymEnabled && openGymEnv) {
ns3TcpSocket->TraceConnectWithoutContext("CongestionWindow",
MakeBoundCallback(&TcpOpenGymEnv::SetCwnd, openGymEnv));
}Simulator::Schedule(Seconds(envStepTime),
&TcpOpenGymEnv::ScheduleNextStateRead, openGymEnv);Complete Deep Q-Network implementation with:
- DQNNetwork: 4-layer neural network for Q-value approximation
- ReplayBuffer: Experience replay with capacity of 10,000 transitions
- DQNAgent: Main agent class with:
- Epsilon-greedy exploration
- Target network (updated every 10 episodes)
- Adam optimizer
- MSE loss function
Hyperparameters:
- Learning rate: 0.001
- Discount factor (γ): 0.99
- Epsilon decay: 0.995 (1.0 → 0.01)
- Batch size: 64
- Hidden layer size: 128 neurons
Features:
- Model saving/loading
- Training and testing modes
- Periodic checkpoint saving
- Progress monitoring
Minimal script for testing the OpenGym connection with random actions.
Complete guide covering:
- Installation instructions
- Usage examples
- Architecture explanation
- Troubleshooting
- Customization guide
Lists all required Python packages:
- torch (PyTorch for DQN)
- numpy (numerical operations)
- gym (RL interface)
- protobuf (communication protocol)
Bash script to verify:
- Python installation
- Required packages
- NS3 installation
- OpenGym module presence
┌─────────────┐ ZMQ Socket ┌─────────────┐
│ │ (Port 5555) │ │
│ NS3 C++ │◄──────────────────────────►│ Python DQN │
│ Simulation │ │ Agent │
│ │ │ │
└─────────────┘ └─────────────┘
│ │
│ 1. GetObservation() │
│────────────────────────────────────────► │
│ │
│ 2. State (CWND, RTT, throughput, etc.) │
│◄──────────────────────────────────────── │
│ │
│ │ 3. DQN decides action
│ │
│ 4. ExecuteActions(action) │
│◄──────────────────────────────────────── │
│ │
│ 5. Apply action to network │
│ │
│ 6. Calculate reward │
│────────────────────────────────────────► │
│ │
│ │ 7. Update Q-network
│ │
└───────────────────────────────────────────┘
- NS3 starts with OpenGym enabled
- Python agent connects to specified port
- Every envStepTime seconds:
- NS3 sends current network state (observation)
- Python DQN agent selects action based on Q-values
- Action is sent back to NS3
- NS3 executes action (modifies network behavior)
- NS3 calculates and sends reward
- Python agent updates Q-network using experience replay
- Process repeats until simulation ends or training completes
# Terminal 1: Start NS3
cd ~/ns-3-dev
./waf --run "tcp --openGym=1"
# Terminal 2: Run random agent
cd /users/mosafer/NS3
python3 simple_train.py# Terminal 1: NS3 with specific parameters
cd ~/ns-3-dev
./waf --run "tcp --openGym=1 --simTime=50 --envStepTime=0.1 --tcpVariant=TcpCubic"
# Terminal 2: DQN training
cd /users/mosafer/NS3
python3 dqn_agent.py --episodes 1000 --save trained_model.pthpython3 dqn_agent.py --test --load trained_model.pthEdit GetObservation() in tcp.cc:
box->AddValue(yourNewMetric); // Add new observationUpdate state_size in Python accordingly.
Edit GetActionSpace() and ExecuteActions() in tcp.cc:
uint32_t actionNum = 7; // Change number of actionsEdit GetReward() in tcp.cc:
float reward = custom_throughput_metric - custom_loss_penalty;Edit DQNAgent.__init__() in dqn_agent.py:
self.gamma = 0.95 # Change discount factor
self.learning_rate = 0.0001 # Change learning rate
self.batch_size = 128 # Change batch size- Early episodes: High exploration (ε ≈ 1.0), random actions, variable rewards
- Mid training: Decreasing exploration, agent starts learning patterns
- Late training: Low exploration (ε → 0.01), consistent policy, higher average rewards
- Increasing average reward over episodes
- Decreasing loss values
- More stable throughput/RTT patterns
- Fewer packet losses
- Multi-flow coordination: Control multiple TCP flows simultaneously
- Prioritized experience replay: Sample important transitions more frequently
- Dueling DQN: Separate value and advantage streams
- Double DQN: Reduce overestimation bias
- Curriculum learning: Start with simple scenarios, increase complexity
- Transfer learning: Pre-train on simpler networks, fine-tune on complex ones
- Compilation: The code will show compile errors for
opengym-module.huntil the OpenGym module is properly installed in NS3 - Port conflicts: Ensure the port (default 5555) is not used by other processes
- Synchronization: NS3 waits for Python agent to respond; ensure agent is running
- Random seed: Use consistent seeds for reproducible experiments
- Step time: Too small
envStepTimeincreases overhead; too large reduces control granularity
- NS3 compiles with OpenGym module
- Python dependencies installed
- NS3 simulation starts without errors
- Python agent connects successfully
- Observations are received and valid
- Actions are applied correctly
- Rewards are calculated properly
- Training progresses (loss decreases)
- Models can be saved and loaded
- Test mode works with trained models
- Install NS3 and OpenGym module (see README_OPENGYM.md)
- Copy tcp.cc to NS3 scratch directory
- Run setup_check.sh to verify installation
- Test with simple_train.py to verify connection
- Begin training with dqn_agent.py
- Monitor and tune hyperparameters
- Evaluate trained model performance
The code is now ready for RL-based TCP congestion control using DQN. The integration provides a flexible framework for experimenting with different RL algorithms and reward functions. The modular design allows easy customization of observations, actions, and rewards to explore various congestion control strategies.