实现 Adhoc DSR 动态自组网
动态源路由协议(DSR)是一种适用于移动自组网(MANET)的路由协议。以下为 Python 实现 DSR 核心功能的详细代码。
网络模块实现
import socket
import threading
import time
import random
import json
from collections import defaultdict
class Node:
def __init__(self, node_id, ip, port):
self.node_id = node_id
self.ip = ip
self.port = port
self.routing_table = {}
self.route_cache = defaultdict(list)
self.seq_num = 0
self.packet_queue = []
self.udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
self.udp_socket.bind((ip, port))
self.neighbors = {}
def send_packet(self, dest_ip, dest_port, packet):
self.udp_socket.sendto(json.dumps(packet).encode(), (dest_ip, dest_port))
路由请求(RREQ)处理
def generate_rreq(self, target_id):
self.seq_num += 1
rreq = {
'type': 'RREQ',
'source_id': self.node_id,
'target_id': target_id,
'seq_num': self.seq_num,
'path': [self.node_id]
}
return rreq
def broadcast_rreq(self, target_id):
rreq = self.generate_rreq(target_id)
for neighbor in self.neighbors.values():
self.send_packet(neighbor['ip'], neighbor['port'], rreq)
def handle_rreq(self, rreq_packet, sender_ip, sender_port):
if self.node_id in rreq_packet['path']:
return
rreq_packet['path'].append(self.node_id)
if rreq_packet['target_id'] == self.node_id:
self.send_rrep(rreq_packet)
else:
for neighbor in self.neighbors.values():
if neighbor['node_id'] not in rreq_packet['path']:
self.send_packet(neighbor['ip'], neighbor['port'], rreq_packet)
路由回复(RREP)处理
def send_rrep(self, rreq_packet):
path = rreq_packet['path']
rrep = {
'type': 'RREP',
'source_id': self.node_id,
'target_id': rreq_packet['source_id'],
'path': path[::-1],
'seq_num': rreq_packet['seq_num']
}
next_hop = path[-2]
neighbor = self.neighbors[next_hop]
self.send_packet(neighbor['ip'], neighbor['port'], rrep)
def handle_rrep(self, rrep_packet):
path = rrep_packet['path']
if rrep_packet['target_id'] == self.node_id:
self.update_route_cache(path)
else:
next_hop_index = path.index(self.node_id) + 1
next_hop_id = path[next_hop_index]
neighbor = self.neighbors[next_hop_id]
self.send_packet(neighbor['ip'], neighbor['port'], rrep_packet)
路由缓存管理
def update_route_cache(self, path):
for i in range(len(path)):
for j in range(i+1, len(path)):
src = path[i]
dst = path[j]
route = path[i:j+1]
if dst not in self.route_cache[src] or len(route) < len(self.route_cache[src][dst]):
self.route_cache[src][dst] = route
def get_cached_route(self, target_id):
if target_id in self.route_cache[self.node_id]:
return self.route_cache[self.node_id][target_id]
return None
数据包转发
def send_data_packet(self, dest_id, data):
cached_route = self.get_cached_route(dest_id)
if cached_route:
packet = {
'type': 'DATA',
'source_id': self.node_id,
'dest_id': dest_id,
'route': cached_route,
'data': data
}
next_hop_id = cached_route[1]
neighbor = self.neighbors[next_hop_id]
self.send_packet(neighbor['ip'], neighbor['port'], packet)
else:
self.broadcast_rreq(dest_id)
self.packet_queue.append((dest_id, data))
def forward_data_packet(self, data_packet):
route = data_packet['route']
current_index = route.index(self.node_id)
if current_index == len(route) - 1:
return # 到达目的地
next_hop_id = route[current_index + 1]
neighbor = self.neighbors[next_hop_id]
self.send_packet(neighbor['ip'], neighbor['port'], data_packet)
邻居发现与维护
def discover_neighbors(self, broadcast_ip, broadcast_port):
hello_packet = {
'type': 'HELLO',
'node_id': self.node_id,
'ip': self.ip,
'port': self.port
}
self.udp_socket.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
self.udp_socket.sendto(json.dumps(hello_packet).encode(),
(broadcast_ip, broadcast_port))
def handle_hello(self, hello_packet):
neighbor_id = hello_packet['node_id']
self.neighbors[neighbor_id] = {
'ip': hello_packet['ip'],
'port': hello_packet['port'],
'node_id': neighbor_id,
'last_seen': time.time()
}
def check_neighbors(self):
current_time = time.time()
dead_neighbors = []
for neighbor_id, info in self.neighbors.items():
if current_time - info['last_seen'] > 30: # 30秒超时
dead_neighbors.append(neighbor_id)
for neighbor_id in dead_neighbors:
del self.neighbors[neighbor_id]
self.purge_routes(neighbor_id)
路由错误处理
def send_rerr(self, broken_link):
rerr = {
'type': 'RERR',
'node_id': self.node_id,
'broken_link': broken_link
}
for neighbor in self.neighbors.values():
self.send_packet(neighbor['ip'], neighbor['port'], rerr)
def handle_rerr(self, rerr_packet):
broken_link = rerr_packet['broken_link']
self.purge_routes(broken_link)
def purge_routes(self, node_id):
for src in list(self.route_cache.keys()):
for dst in list(self.route_cache[src].keys()):
if node_id in self.route_cache[src][dst]:
del self.route_cache[src][dst]
主事件循环
def start(self):
def listener():
while True:
data, addr = self.udp_socket.recvfrom(1024)
packet = json.loads(data.decode())
self.handle_packet(packet, addr[0], addr[1])
def neighbor_checker():
while True:
time.sleep(10)
self.check_neighbors()
threading.Thread(target=listener, daemon=True).start()
threading.Thread(target=neighbor_checker, daemon=True).start()
def handle_packet(self, packet, sender_ip, sender_port):
if packet['type'] == 'HELLO':
self.handle_hello(packet)
elif packet['type'] == 'RREQ':
self.handle_rreq(packet, sender_ip, sender_port)
elif packet['type'] == 'RREP':
self.handle_rrep(packet)
elif packet['type'] == 'DATA':
if packet['dest_id'] == self.node_id:
print(f"Received data: {packet['data']}")
else:
self.forward_data_packet(packet)
elif packet['type'] == 'RERR':
self.handle_rerr(packet)
测试网络设置
if __name__ == "__main__":
nodes = []
ports = [5000, 5001, 5002, 5003]
for i, port in enumerate(ports):
node = Node(f"node_{i}", "127.0.0.1", port)
nodes.append(node)
node.start()
# 模拟邻居发现
for node in nodes:
node.discover_neighbors("127.0.0.1", 5000)
node.discover_neighbors("127.0.0.1", 5001)
node.discover_neighbors("127.0.0.1", 5002)
node.discover_neighbors("127.0.0.1", 5003)
time.sleep(1)
# 发送测试数据
nodes[0].send_data_packet("node_3", "Hello from node 0")
while True:
time.sleep(1)
关键功能说明
- 邻居发现通过HELLO消息实现周期性维护
- 路由请求(RREQ)采用广播方式扩散
- 路由回复(RREP)沿反向路径返回
- 路由错误(RERR)通知链路中断
- 数据包携带完整路由信息
- 路由缓存优化减少RREQ广播
实现中需要注意网络拓扑变化时的路由更新,以及适当设置超时时间。该实现提供了DSR的核心功能框架,可根据实际需求扩展优化。
1273

被折叠的 条评论
为什么被折叠?



