实现 Adhoc DSR 动态自组网

实现 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的核心功能框架,可根据实际需求扩展优化。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值