diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..363efb6
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,30 @@
+
+
+ 4.0.0
+
+ cn.x47
+ rip
+ 1.0-SNAPSHOT
+
+
+ 8
+ 8
+ UTF-8
+
+
+
+
+ io.netty
+ netty-all
+ 4.1.68.Final
+
+
+ org.projectlombok
+ lombok
+ 1.18.34
+
+
+
+
diff --git a/src/main/java/cn/x47/RIPService.java b/src/main/java/cn/x47/RIPService.java
new file mode 100644
index 0000000..3b51a6a
--- /dev/null
+++ b/src/main/java/cn/x47/RIPService.java
@@ -0,0 +1,70 @@
+package cn.x47;
+
+
+import cn.x47.config.Config;
+import cn.x47.model.RIPEntry;
+import cn.x47.model.RIPPacket;
+import cn.x47.service.RIPClient;
+import cn.x47.service.RIPServer;
+
+import java.net.InetAddress;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.*;
+
+public class RIPService {
+
+ public static void main(String[] args) throws Exception {
+ // 启动服务器
+ RIPServer server = new RIPServer();
+ new Thread(() -> {
+ try {
+ server.start();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }).start();
+
+ // 启动客户端
+ RIPClient client = new RIPClient();
+
+ // 定期发送路由更新
+ ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
+ scheduler.scheduleAtFixedRate(() -> {
+ RIPPacket packet = createRipResponsePacket(Config.RIP_VERSION);
+ client.sendRipPacket(packet);
+ }, 0, 30, TimeUnit.SECONDS);
+
+// 主线程等待
+ Thread.currentThread().join();
+ }
+
+ private static RIPPacket createRipResponsePacket(byte version) {
+ List entries = new ArrayList<>();
+
+ try {
+ // 示例:添加本地路由条目
+ InetAddress localAddress = InetAddress.getByName("192.168.100.0");
+ InetAddress subnetMask = InetAddress.getByName("255.255.255.0");
+ InetAddress nextHop = InetAddress.getByName("192.168.123.45");
+
+ RIPEntry entry = new RIPEntry();
+ entry.setAddressFamily((short) 2); // AF_INET
+ entry.setIpAddress(localAddress);
+ entry.setMetric(1);
+
+ if (version == 2) {
+ entry.setRouteTag((short) 0);
+ entry.setSubnetMask(subnetMask);
+ entry.setNextHop(nextHop);
+ }
+
+ entries.add(entry);
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ return new RIPPacket((byte) 2, version, entries); // Command=2 (Response)
+ }
+}
diff --git a/src/main/java/cn/x47/config/Config.java b/src/main/java/cn/x47/config/Config.java
new file mode 100644
index 0000000..2340d09
--- /dev/null
+++ b/src/main/java/cn/x47/config/Config.java
@@ -0,0 +1,6 @@
+package cn.x47.config;
+
+public class Config {
+ // 设置协议版本,1 表示 RIP v1,2 表示 RIP v2
+ public static final byte RIP_VERSION = 2;
+}
diff --git a/src/main/java/cn/x47/handle/RIPPacketDecoder.java b/src/main/java/cn/x47/handle/RIPPacketDecoder.java
new file mode 100644
index 0000000..4184cf4
--- /dev/null
+++ b/src/main/java/cn/x47/handle/RIPPacketDecoder.java
@@ -0,0 +1,64 @@
+package cn.x47.handle;
+
+
+import cn.x47.model.RIPEntry;
+import cn.x47.model.RIPPacket;
+import io.netty.buffer.ByteBuf;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.channel.socket.DatagramPacket;
+import io.netty.handler.codec.MessageToMessageDecoder;
+
+import java.net.InetAddress;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 解码器
+ */
+public class RIPPacketDecoder extends MessageToMessageDecoder {
+
+ @Override
+ protected void decode(ChannelHandlerContext ctx, DatagramPacket packet, List