修复组播无法接收
This commit is contained in:
		@@ -8,6 +8,8 @@ import cn.x47.service.RIPClient;
 | 
				
			|||||||
import cn.x47.service.RIPServer;
 | 
					import cn.x47.service.RIPServer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import java.net.InetAddress;
 | 
					import java.net.InetAddress;
 | 
				
			||||||
 | 
					import java.net.SocketException;
 | 
				
			||||||
 | 
					import java.net.UnknownHostException;
 | 
				
			||||||
import java.util.ArrayList;
 | 
					import java.util.ArrayList;
 | 
				
			||||||
import java.util.List;
 | 
					import java.util.List;
 | 
				
			||||||
import java.util.concurrent.Executors;
 | 
					import java.util.concurrent.Executors;
 | 
				
			||||||
@@ -25,6 +27,8 @@ public class RIPService {
 | 
				
			|||||||
                    server.start();
 | 
					                    server.start();
 | 
				
			||||||
                } catch (InterruptedException e) {
 | 
					                } catch (InterruptedException e) {
 | 
				
			||||||
                    e.printStackTrace();
 | 
					                    e.printStackTrace();
 | 
				
			||||||
 | 
					                } catch (SocketException | UnknownHostException e) {
 | 
				
			||||||
 | 
					                    throw new RuntimeException(e);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }).start();
 | 
					            }).start();
 | 
				
			||||||
            System.out.println("服务端已经启动");
 | 
					            System.out.println("服务端已经启动");
 | 
				
			||||||
@@ -52,8 +56,8 @@ public class RIPService {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        try {
 | 
					        try {
 | 
				
			||||||
            // 示例:添加本地路由条目
 | 
					            // 示例:添加本地路由条目
 | 
				
			||||||
            InetAddress localAddress = InetAddress.getByName("10.47.54.0");
 | 
					            InetAddress localAddress = InetAddress.getByName("10.110.80.52");
 | 
				
			||||||
            InetAddress subnetMask = InetAddress.getByName("255.255.255.0");
 | 
					            InetAddress subnetMask = InetAddress.getByName("255.255.255.255");
 | 
				
			||||||
            InetAddress nextHop = InetAddress.getByName("0.0.0.0");
 | 
					            InetAddress nextHop = InetAddress.getByName("0.0.0.0");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            RIPEntry entry = new RIPEntry();
 | 
					            RIPEntry entry = new RIPEntry();
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,7 +2,7 @@ package cn.x47.config;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
public class Config {
 | 
					public class Config {
 | 
				
			||||||
    // 设置协议版本,1 表示 RIP v1,2 表示 RIP v2
 | 
					    // 设置协议版本,1 表示 RIP v1,2 表示 RIP v2
 | 
				
			||||||
    public static final byte RIP_VERSION = 1;
 | 
					    public static final byte RIP_VERSION = 2;
 | 
				
			||||||
    public static final boolean startServer = true;
 | 
					    public static final boolean startServer = true;
 | 
				
			||||||
    public static final boolean startClient = false;
 | 
					    public static final boolean startClient = true;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,12 +4,14 @@ package cn.x47.handle;
 | 
				
			|||||||
import cn.x47.model.RIPEntry;
 | 
					import cn.x47.model.RIPEntry;
 | 
				
			||||||
import cn.x47.model.RIPPacket;
 | 
					import cn.x47.model.RIPPacket;
 | 
				
			||||||
import io.netty.buffer.ByteBuf;
 | 
					import io.netty.buffer.ByteBuf;
 | 
				
			||||||
 | 
					import io.netty.buffer.ByteBufUtil;
 | 
				
			||||||
import io.netty.channel.ChannelHandlerContext;
 | 
					import io.netty.channel.ChannelHandlerContext;
 | 
				
			||||||
import io.netty.channel.socket.DatagramPacket;
 | 
					import io.netty.channel.socket.DatagramPacket;
 | 
				
			||||||
import io.netty.handler.codec.MessageToMessageDecoder;
 | 
					import io.netty.handler.codec.MessageToMessageDecoder;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import java.net.InetAddress;
 | 
					import java.net.InetAddress;
 | 
				
			||||||
import java.util.ArrayList;
 | 
					import java.util.ArrayList;
 | 
				
			||||||
 | 
					import java.util.Arrays;
 | 
				
			||||||
import java.util.List;
 | 
					import java.util.List;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
@@ -42,8 +44,16 @@ public class RIPPacketDecoder extends MessageToMessageDecoder<DatagramPacket> {
 | 
				
			|||||||
            if (ripPacket.getVersion() == 1) {
 | 
					            if (ripPacket.getVersion() == 1) {
 | 
				
			||||||
                // 对于 RIP v1,子网掩码和下一跳需要推断或设为默认值
 | 
					                // 对于 RIP v1,子网掩码和下一跳需要推断或设为默认值
 | 
				
			||||||
                entry.setSubnetMask(InetAddress.getByName("255.255.255.0")); // 示例,实际应根据 IP 类推断
 | 
					                entry.setSubnetMask(InetAddress.getByName("255.255.255.0")); // 示例,实际应根据 IP 类推断
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            byte[] address = entry.getNextHop().getAddress();
 | 
				
			||||||
 | 
					            byte[] address1 = InetAddress.getByName("0.0.0.0").getAddress();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if(Arrays.equals(address, address1)) {
 | 
				
			||||||
                entry.setNextHop(packet.sender().getAddress());
 | 
					                entry.setNextHop(packet.sender().getAddress());
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            entry.setMetric((int) buf.readUnsignedInt());
 | 
					            entry.setMetric((int) buf.readUnsignedInt());
 | 
				
			||||||
            entries.add(entry);
 | 
					            entries.add(entry);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -11,7 +11,6 @@ public class RIPServerHandler extends SimpleChannelInboundHandler<RIPPacket> {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    @Override
 | 
					    @Override
 | 
				
			||||||
    protected void channelRead0(ChannelHandlerContext ctx, RIPPacket msg) throws Exception {
 | 
					    protected void channelRead0(ChannelHandlerContext ctx, RIPPacket msg) throws Exception {
 | 
				
			||||||
        System.out.println(msg);
 | 
					 | 
				
			||||||
        if (msg.getCommand() == 2) { // Response
 | 
					        if (msg.getCommand() == 2) { // Response
 | 
				
			||||||
            for (RIPEntry entry : msg.getEntries()) {
 | 
					            for (RIPEntry entry : msg.getEntries()) {
 | 
				
			||||||
                // 更新本地路由表
 | 
					                // 更新本地路由表
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -11,26 +11,68 @@ import io.netty.channel.nio.NioEventLoopGroup;
 | 
				
			|||||||
import io.netty.channel.socket.DatagramChannel;
 | 
					import io.netty.channel.socket.DatagramChannel;
 | 
				
			||||||
import io.netty.channel.socket.nio.NioDatagramChannel;
 | 
					import io.netty.channel.socket.nio.NioDatagramChannel;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import java.net.*;
 | 
				
			||||||
 | 
					import java.util.ArrayList;
 | 
				
			||||||
 | 
					import java.util.Enumeration;
 | 
				
			||||||
 | 
					import java.util.List;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public class RIPServer {
 | 
					public class RIPServer {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public void start() throws InterruptedException {
 | 
					    public void start() throws InterruptedException, UnknownHostException, SocketException {
 | 
				
			||||||
        NioEventLoopGroup group = new NioEventLoopGroup();
 | 
					        NioEventLoopGroup group = new NioEventLoopGroup();
 | 
				
			||||||
        try {
 | 
					        try {
 | 
				
			||||||
            Bootstrap b = new Bootstrap();
 | 
					            Bootstrap b = new Bootstrap();
 | 
				
			||||||
            b.group(group)
 | 
					            b.group(group)
 | 
				
			||||||
                    .channel(NioDatagramChannel.class)
 | 
					                    .channel(NioDatagramChannel.class)
 | 
				
			||||||
                    .option(ChannelOption.SO_BROADCAST, true)
 | 
					                    .option(ChannelOption.SO_BROADCAST, true)
 | 
				
			||||||
 | 
					                    .option(ChannelOption.IP_MULTICAST_LOOP_DISABLED, true)
 | 
				
			||||||
                    .handler(new ChannelInitializer<DatagramChannel>() {
 | 
					                    .handler(new ChannelInitializer<DatagramChannel>() {
 | 
				
			||||||
                        @Override
 | 
					                        @Override
 | 
				
			||||||
                        protected void initChannel(DatagramChannel ch) throws Exception {
 | 
					                        protected void initChannel(DatagramChannel ch) throws Exception {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                            ch.pipeline().addLast(new RIPPacketDecoder(), new RIPServerHandler());
 | 
					                            ch.pipeline().addLast(new RIPPacketDecoder(), new RIPServerHandler());
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                    });
 | 
					                    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            ChannelFuture future = b.bind(520).sync();
 | 
					            ChannelFuture future = b.bind(520).sync();
 | 
				
			||||||
 | 
					            // 获取并加入组播组
 | 
				
			||||||
 | 
					            NioDatagramChannel channel = (NioDatagramChannel) future.channel();
 | 
				
			||||||
 | 
					            InetAddress multicastAddress = InetAddress.getByName("224.0.0.9"); // 替换为你的组播地址
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // 自动获取网络接口并加入组播组
 | 
				
			||||||
 | 
					            List<NetworkInterface> multicastInterfaces = getMulticastInterfaces();
 | 
				
			||||||
 | 
					            for (NetworkInterface networkInterface : multicastInterfaces) {
 | 
				
			||||||
 | 
					                channel.joinGroup(new InetSocketAddress(multicastAddress, 520), networkInterface).sync();
 | 
				
			||||||
 | 
					                System.out.println("已在接口 " + networkInterface.getName() + " 上加入组播组");
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            System.out.println("监听器已启动,正在监听端口:" + 520);
 | 
				
			||||||
            future.channel().closeFuture().await();
 | 
					            future.channel().closeFuture().await();
 | 
				
			||||||
        } finally {
 | 
					        } finally {
 | 
				
			||||||
            group.shutdownGracefully();
 | 
					            group.shutdownGracefully();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private List<NetworkInterface> getMulticastInterfaces() throws SocketException {
 | 
				
			||||||
 | 
					        List<NetworkInterface> interfaces = new ArrayList<>();
 | 
				
			||||||
 | 
					        Enumeration<NetworkInterface> networkInterfaces = NetworkInterface.getNetworkInterfaces();
 | 
				
			||||||
 | 
					        while (networkInterfaces.hasMoreElements()) {
 | 
				
			||||||
 | 
					            NetworkInterface networkInterface = networkInterfaces.nextElement();
 | 
				
			||||||
 | 
					            if (networkInterface.isUp() && !networkInterface.isLoopback() && networkInterface.supportsMulticast()) {
 | 
				
			||||||
 | 
					                // 检查是否有 IPv4 地址
 | 
				
			||||||
 | 
					                Enumeration<InetAddress> addresses = networkInterface.getInetAddresses();
 | 
				
			||||||
 | 
					                boolean hasIPv4 = false;
 | 
				
			||||||
 | 
					                while (addresses.hasMoreElements()) {
 | 
				
			||||||
 | 
					                    InetAddress address = addresses.nextElement();
 | 
				
			||||||
 | 
					                    if (address instanceof Inet4Address) {
 | 
				
			||||||
 | 
					                        hasIPv4 = true;
 | 
				
			||||||
 | 
					                        break;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                if (hasIPv4) {
 | 
				
			||||||
 | 
					                    interfaces.add(networkInterface);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return interfaces;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user