Compare commits

...

3 Commits

Author SHA1 Message Date
757b781f30 修复组播无法接收 2024-12-01 23:06:34 +08:00
497f55c40c 优化 服务端,客户端代码 解决读取错位的问题。 2024-12-01 20:33:49 +08:00
638507e0f3 优化 服务端 客户端代码 2024-12-01 17:59:34 +08:00
5 changed files with 73 additions and 22 deletions

View File

@ -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>

View File

@ -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();

View File

@ -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)); if (ripPacket.getVersion() == 1) {
} else {
// 对于 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);

View File

@ -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) {

View File

@ -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;
}
} }