-
Notifications
You must be signed in to change notification settings - Fork 59
Description
Describe the bug
- The QunetSim classical channel is not delivering messages.
- The problem is with QunetSim, not your code.
To Reproduce
import select
from sctp import sctpsocket_tcp
from socket import AF_INET
from threading import Thread
from qunetsim.components import Host, Network
from qunetsim.objects.connections.classical_connection import ClassicalConnection
from qunetsim.backends import EQSNBackend
import time
Network Configuration
CU_IP = "10.108.202.32"
DU_IP = "10.108.202.33"
TUNNEL_IP = "10.109.202.32"
SCTP_PORT = 38472
BUFFER_SIZE = 128384
POLL_INTERVAL = 0.3
class QuantumTunnel:
def init(self):
self.setup_sockets()
self.data_counter = 0
self.debug = True
self.setup_quantum_network()
def debug_print(self, message):
if self.debug:
print(f"[DEBUG] {message}")
def setup_sockets(self):
self.server_socket = sctpsocket_tcp(AF_INET)
self.server_socket.bind((TUNNEL_IP, SCTP_PORT))
self.server_socket.listen(1)
self.du_conn, self.du_addr = self.server_socket.accept()
self.du_conn.setblocking(False)
print(f"[INFO] DU connected from {self.du_addr}")
self.cu_socket = sctpsocket_tcp(AF_INET)
self.cu_socket.connect((DU_IP, SCTP_PORT))
self.cu_socket.setblocking(False)
print("[INFO] Connected to CU")
def setup_quantum_network(self):
# Set the backend explicitly to EQSN
Network.get_instance().backend = EQSNBackend()
# Initialize hosts
self.qdu = Host('QDU')
self.qcu = Host('QCU')
# Create classical connection
self.debug_print("Creating classical connection between QDU and QCU")
connection = ClassicalConnection('QDU', 'QCU')
self.qdu.add_connection(connection)
self.qcu.add_connection(connection)
# QDU protocol: receives from QCU and forwards to DU
@self.qdu.run_protocol
def qdu_protocol(host):
print("[INFO] QDU protocol started")
while True:
self.debug_print("QDU polling for messages from QCU")
message = host.get_next_classical('QCU')
if message is not None:
self.debug_print(f"QDU received from QCU: {str(message.content)[:20]}...")
self.forward_to_du(message.content)
time.sleep(0.1)
# QCU protocol: receives from QDU and forwards to CU
@self.qcu.run_protocol
def qcu_protocol(host):
print("[INFO] QCU protocol started")
while True:
self.debug_print("QCU polling for messages from QDU")
message = host.get_next_classical('QDU')
if message is not None:
self.debug_print(f"QCU received from QDU: {str(message.content)[:20]}...")
self.forward_to_cu(message.content)
time.sleep(0.1)
# Initialize network
self.network = Network.get_instance()
self.debug_print("Adding hosts to network...")
self.network.add_host(self.qdu)
self.network.add_host(self.qcu)
self.network.start()
print("[INFO] Quantum network initialized")
# External data handlers
def receive_from_du(self, data):
self.data_counter += 1
self.debug_print(f"QDU received external data from DU: {len(data)} bytes (message #{self.data_counter})")
self.qdu.send_classical('QCU', data)
self.debug_print(f"QDU sent to QCU (message #{self.data_counter})")
def receive_from_cu(self, data):
self.data_counter += 1
self.debug_print(f"QCU received external data from CU: {len(data)} bytes (message #{self.data_counter})")
self.qcu.send_classical('QDU', data)
self.debug_print(f"QCU sent to QDU (message #{self.data_counter})")
# Internal forwarding
def forward_to_du(self, data):
try:
self.du_conn.send(data)
self.debug_print(f"Forwarded {len(data)} bytes to DU")
except Exception as e:
print(f"[ERROR] Failed to forward to DU: {e}")
def forward_to_cu(self, data):
try:
self.cu_socket.send(data)
self.debug_print(f"Forwarded {len(data)} bytes to CU")
except Exception as e:
print(f"[ERROR] Failed to forward to CU: {e}")
# Socket handlers
def handle_du_data(self):
print("[INFO] DU handler started")
while True:
try:
data = self.du_conn.recv(BUFFER_SIZE)
if data:
self.receive_from_du(data)
except Exception as e:
if str(e) != "[Errno 11] Resource temporarily unavailable":
print(f"[ERROR] DU receive error: {e}")
time.sleep(0.1)
def handle_cu_data(self):
print("[INFO] CU handler started")
while True:
try:
data = self.cu_socket.recv(BUFFER_SIZE)
if data:
self.receive_from_cu(data)
except Exception as e:
if str(e) != "[Errno 11] Resource temporarily unavailable":
print(f"[ERROR] CU receive error: {e}")
time.sleep(0.1)
def run(self):
du_thread = Thread(target=self.handle_du_data)
cu_thread = Thread(target=self.handle_cu_data)
du_thread.daemon = True
cu_thread.daemon = True
du_thread.start()
cu_thread.start()
print("[INFO] Tunnel is running...")
try:
while True:
select.select([self.server_socket, self.cu_socket], [], [], POLL_INTERVAL)
except KeyboardInterrupt:
print("\n[INFO] Shutting down tunnel...")
finally:
self.cleanup()
def cleanup(self):
try:
self.du_conn.close()
self.cu_socket.close()
self.server_socket.close()
print("[INFO] Connections closed")
except Exception as e:
print(f"[ERROR] Cleanup error: {e}")
if name == "main":
tunnel = QuantumTunnel()
tunnel.run()
Expected behavior
I want the hosts (QDU and QCU) to mutually communicate
Screenshots
System:
-
OS: PRETTY_NAME="Ubuntu 22.04.5 LTS"
NAME="Ubuntu"
VERSION_ID="22.04"
VERSION="22.04.5 LTS (Jammy Jellyfish)"
VERSION_CODENAME=jammy
ID=ubuntu
ID_LIKE=debian
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
UBUNTU_CODENAME=jammy -
Python Version:
Python 3.10.12
Additional context
I am not able to send data from QDU ---------->QCU and vice-versa communication, its stuck like sending from QDU to QCU
the timeout is because the data is not received at the other ping pong server it reset the connection.
