我正在尝试为一个小服务器编写数据包监听器.我是
Java的新手,这是我第一次搞乱网络.整个想法是重新接收数据包,将数据包id与它的类匹配,将输入流传递给数据包的构造函数,以便可以构造它然后将其提供给packetHander,它将为每个数据包提供重叠方法.要使用将数据包ID映射到每个类的数组,并使用一个名为decode的方法来构造数据包,来实现这个im.问题是handlePacket的重载它没有按预期运行.让我们看一些代码.
我在一个线程中运行数据包监听器,run方法如下所示:
public void run() {
try {
int packet_id;
while ((packet_id = istream.readInt()) != -1) {
plugin.getServer().getConsoleSender().sendMessage("[Comm] Recived packet " + packet_id);
Packet packet = decode(packet_id, istream);
plugin.getServer().getConsoleSender().sendMessage("[Comm] Packet is " + Class.forName(packet.getClass().getName()));
plugin.getServer().getConsoleSender().sendMessage("[Comm] Class is " + Packet00ReqIdentify.class.cast(packet).getClass().getName());
plugin.getServer().getConsoleSender().sendMessage("[Comm] Class is " + Class.forName(packet.getClass().getName()).getName());
handlePacket(packet);
}
} catch (IOException | NoSuchMethodException | SecurityException | InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException | ClassNotFoundException e) {
e.printStackTrace();
}
}
decode和handlePacket方法如下所示:
private void handlePacket(Packet00ReqIdentify packet) throws IOException {
plugin.getServer().getConsoleSender().sendMessage("[Comm] Got it!");
}
private void handlePacket(Packet packet) {
plugin.getServer().getConsoleSender().sendMessage("[Comm] Woops!");
}
private Packet decode(int packet_id, PacketInputStream istream) throws NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, ClassNotFoundException, IOException {
Class extends Packet> packet_class = packets_ids.get(packet_id);
try {
Constructor> packet_constructor = packet_class.getConstructor(PacketInputStream.class);
return Class.forName(packet_class.getName()).asSubclass(Packet.class).cast(packet_constructor.newInstance(istream));
} catch (NoSuchMethodException e) {
return Class.forName(packet_class.getName()).asSubclass(Packet.class).cast(packet_class.newInstance());
}
}
packets_ids它是一个数组,包含对每个数据包类的引用,由他们的id索引:
private static ArrayList> packets_ids;
它以这种方式初始化:
private static void registerPacket(int id, Class extends Packet> oclass) {
packets_ids.add(id, oclass);
}
static {
packets_ids = new ArrayList>();
registerPacket(Packet00ReqIdentify.assigned_pid, Packet00ReqIdentify.class);
registerPacket(Packet01Identify.assigned_pid, Packet01Identify.class);
registerPacket(Packet02Heartbeat.assigned_pid, Packet02Heartbeat.class);
}
如果我执行此操作并测试它发送类型为00的数据包,我得到这个:
17:37:49 [INFO] [Comm] Connection established to localhost:11000
17:37:49 [INFO] [Comm] Recived packet 0
17:37:49 [INFO] [Comm] Packet is class com.gamerarg.commclient.protocol.Packet00ReqIdentify
17:37:49 [INFO] [Comm] Class is com.gamerarg.commclient.protocol.Packet00ReqIdentify
17:37:49 [INFO] [Comm] Class is com.gamerarg.commclient.protocol.Packet00ReqIdentify
17:37:49 [INFO] [Comm] Woops!
所以这意味着packet00还没有被“handlePacket(Packet00ReqIdentify packet)”所捕获.如果我在handlePacket调用中对“packet”进行显式转换,则它可以工作.所以问题是:
>为什么这不起作用?当我打印两个类名时,我得到相同的.
>我怎样才能让它发挥作用?我现在一直在努力工作6到7个小时,阅读,谷歌搜索,尝试和查看其他人的代码.一个更简单的解决方案是使用数据包ID进行切换,但我想要更优雅的东西. Maybye我的基本想法是错的,这就是我发布代码的原因,我对这个主题中更有经验的人的建议和想法持开放态度,包括对主题材料的推荐.
谢谢!