Compare commits
3 Commits
a9afea0603
...
v2
Author | SHA1 | Date | |
---|---|---|---|
757b781f30
|
|||
497f55c40c
|
|||
638507e0f3
|
2
pom.xml
2
pom.xml
@ -18,7 +18,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.netty</groupId>
|
<groupId>io.netty</groupId>
|
||||||
<artifactId>netty-all</artifactId>
|
<artifactId>netty-all</artifactId>
|
||||||
<version>4.1.68.Final</version>
|
<version>4.1.110.Final</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.projectlombok</groupId>
|
<groupId>org.projectlombok</groupId>
|
||||||
|
@ -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("服务端已经启动");
|
||||||
@ -38,6 +42,7 @@ public class RIPService {
|
|||||||
scheduler.scheduleAtFixedRate(() -> {
|
scheduler.scheduleAtFixedRate(() -> {
|
||||||
RIPPacket packet = createRipResponsePacket(Config.RIP_VERSION);
|
RIPPacket packet = createRipResponsePacket(Config.RIP_VERSION);
|
||||||
client.sendRipPacket(packet);
|
client.sendRipPacket(packet);
|
||||||
|
System.out.println("客户端 发送了一次消息");
|
||||||
}, 0, 10, TimeUnit.SECONDS);
|
}, 0, 10, TimeUnit.SECONDS);
|
||||||
System.out.println("客户端已经启动");
|
System.out.println("客户端已经启动");
|
||||||
}
|
}
|
||||||
@ -51,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();
|
||||||
|
@ -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;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -29,26 +31,30 @@ public class RIPPacketDecoder extends MessageToMessageDecoder<DatagramPacket> {
|
|||||||
while (buf.readableBytes() >= 20) {
|
while (buf.readableBytes() >= 20) {
|
||||||
RIPEntry entry = new RIPEntry();
|
RIPEntry entry = new RIPEntry();
|
||||||
entry.setAddressFamily(buf.readShort());
|
entry.setAddressFamily(buf.readShort());
|
||||||
if (ripPacket.getVersion() == 2) {
|
|
||||||
entry.setRouteTag(buf.readShort());
|
entry.setRouteTag(buf.readShort());
|
||||||
} else {
|
|
||||||
entry.setRouteTag((short) 0);
|
|
||||||
}
|
|
||||||
byte[] ipBytes = new byte[4];
|
byte[] ipBytes = new byte[4];
|
||||||
buf.readBytes(ipBytes);
|
buf.readBytes(ipBytes);
|
||||||
entry.setIpAddress(InetAddress.getByAddress(ipBytes));
|
entry.setIpAddress(InetAddress.getByAddress(ipBytes));
|
||||||
|
|
||||||
if (ripPacket.getVersion() == 2) {
|
|
||||||
buf.readBytes(ipBytes);
|
buf.readBytes(ipBytes);
|
||||||
entry.setSubnetMask(InetAddress.getByAddress(ipBytes));
|
entry.setSubnetMask(InetAddress.getByAddress(ipBytes));
|
||||||
buf.readBytes(ipBytes);
|
buf.readBytes(ipBytes);
|
||||||
entry.setNextHop(InetAddress.getByAddress(ipBytes));
|
entry.setNextHop(InetAddress.getByAddress(ipBytes));
|
||||||
} else {
|
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(buf.readInt());
|
|
||||||
|
entry.setMetric((int) buf.readUnsignedInt());
|
||||||
entries.add(entry);
|
entries.add(entry);
|
||||||
}
|
}
|
||||||
ripPacket.setEntries(entries);
|
ripPacket.setEntries(entries);
|
||||||
|
@ -11,9 +11,6 @@ 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.InetAddress;
|
|
||||||
import java.net.UnknownHostException;
|
|
||||||
|
|
||||||
|
|
||||||
public class RIPClient {
|
public class RIPClient {
|
||||||
|
|
||||||
@ -36,8 +33,7 @@ public class RIPClient {
|
|||||||
|
|
||||||
public void sendRipPacket(RIPPacket packet) {
|
public void sendRipPacket(RIPPacket packet) {
|
||||||
try {
|
try {
|
||||||
ChannelFuture future = bootstrap.bind(0)
|
ChannelFuture future = bootstrap.bind(0).sync();
|
||||||
.sync();
|
|
||||||
future.channel().writeAndFlush(packet).sync();
|
future.channel().writeAndFlush(packet).sync();
|
||||||
future.channel().close();
|
future.channel().close();
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
|
@ -4,31 +4,75 @@ package cn.x47.service;
|
|||||||
import cn.x47.handle.RIPPacketDecoder;
|
import cn.x47.handle.RIPPacketDecoder;
|
||||||
import cn.x47.handle.RIPServerHandler;
|
import cn.x47.handle.RIPServerHandler;
|
||||||
import io.netty.bootstrap.Bootstrap;
|
import io.netty.bootstrap.Bootstrap;
|
||||||
import io.netty.channel.*;
|
import io.netty.channel.ChannelFuture;
|
||||||
|
import io.netty.channel.ChannelInitializer;
|
||||||
|
import io.netty.channel.ChannelOption;
|
||||||
import io.netty.channel.nio.NioEventLoopGroup;
|
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