Java套接字连接:从输入流接收完全任意的整数
我一直在学习Java中的套接字,它可以在两个独立的Java应用程序之间为我正在开发的一个小游戏程序发送信息。目标是能够拥有它,以便服务器A可以通过在switch语句中写入和读取int来告诉服务器B做一些事情。这是我为服务器端套接字编写的代码:Java套接字连接:从输入流接收完全任意的整数,java,sockets,minecraft,serversocket,Java,Sockets,Minecraft,Serversocket,我一直在学习Java中的套接字,它可以在两个独立的Java应用程序之间为我正在开发的一个小游戏程序发送信息。目标是能够拥有它,以便服务器A可以通过在switch语句中写入和读取int来告诉服务器B做一些事情。这是我为服务器端套接字编写的代码: @Override public void run() { try ( DataInputStream input = new DataInputStream(this.socket.getInputStream())
@Override
public void run() {
try (
DataInputStream input = new DataInputStream(this.socket.getInputStream())
) {
this.output = new DataOutputStream(this.socket.getOutputStream());
while (!this.finished) {
int type = input.readInt();
this.plugin.getLogger().info("Type: " + type + " from " + this.socket.getRemoteSocketAddress());
switch (type) {
case 1: {
ServerManager.getInstance().addActiveServer(this.serverInfo, input.readInt());
break;
}
case 2: {
int length = input.readInt();
for (int i = 0; i < length; i++) {
UUID uuid = UUID.fromString(input.readUTF());
PlayerData playerData = PlayerManager.getInstance().getPlayerData(uuid);
if (playerData == null) {
continue;
}
playerData.setPlaying(false);
playerData.setSpectating(false);
playerData.setQueuing(false);
playerData.getPlayer().connect(this.plugin.getLobbyServer());
}
ServerManager.getInstance().addInactiveServer(this.serverInfo);
break;
}
case 3: {
int length = input.readInt();
for (int i = 0; i < length; i++) {
UUID uniqueId = UUID.fromString(input.readUTF());
PlayerData playerData = PlayerManager.getInstance().getPlayerData(uniqueId);
if (playerData == null) {
continue;
}
playerData.setQueuing(true);
}
break;
}
default:
}
}
this.output.close();
this.socket.close();
} catch (Exception e) {
e.printStackTrace();
}
}
当小游戏结束并且程序通知服务器A小游戏结束时,也会发生此问题。直到我对下面的代码做了一点修改,我才发现这个问题:
public void sendPlayingUpdate(@NotNull Collection<UUID> players) throws IOException {
this.output.writeBoolean(true);
this.output.writeBoolean(false);
this.output.writeBoolean(false);
this.output.writeInt(5);
this.output.writeInt(players.size());
for (UUID player : players) {
this.output.writeUTF(String.valueOf(player));
}
// this.output.writeInt(4);
// this.output.writeInt(players.size());
// for (UUID uuid : players) {
// this.output.writeUTF(String.valueOf(uuid));
// }
this.output.flush();
}
public void sendPlayingUpdate(@NotNull Collection players)引发IOException{
this.output.writebolean(true);
this.output.writebolean(false);
this.output.writebolean(false);
这个.output.writeInt(5);
this.output.writeInt(players.size());
用于(UUID玩家:玩家){
this.output.writeUTF(String.valueOf(player));
}
//这个.output.writeInt(4);
//this.output.writeInt(players.size());
//用于(UUID UUID:玩家){
//this.output.writeUTF(String.valueOf(uuid));
// }
this.output.flush();
}
注释掉的位是原始代码。如果我用未注释的代码替换它,它会给出所有这些任意大的整数。是否有其他应用程序以某种方式连接到与套接字相同的端口并开始提供随机信息的方法?我只是不明白一个小小的改变怎么会导致像1667643705这样的东西被发送,整数真的让我想起了哈希代码
非常感谢。从您的服务器端代码判断,您的协议似乎如下所示
- 数据包ID(int):4字节
- N字节的数据包特定内容
我建议为您的数据包处理逻辑创建一个单元测试,其中您创建一个只包含单个数据包的DataInputStream。对于每个数据包,您都要检查它是否被正确处理,以及处理后是否有任何剩余数据。这将使您能够找到问题。时间戳表示第二个和第三个数据包之间有16秒的间隔。因此,可能不是第二个
3
数据包损坏。在其他地方,您正在发送一个格式错误的数据包,代码未显示
数据如下:
01 00 00 00 00 00 05 00 00 00 01 00 24 [... load of hex ...]
0x24
是$
,但可以是writeUTF
中的字符串长度-例如,两个UUID连接在一起
我将开始测试解析代码,它可以解释格式代码的输出,而不需要所有服务器的东西。作为一个好处,这将需要更好地分解代码。Bro在我看来,您可能在同一端口上运行了其他东西-使用netstat-ano检查CMD,在任务管理器中也可以查看当前连接。您可能有多个实例使用所选端口号在同一端口或其他应用程序上发送或侦听-让我们尝试更改端口号,如果有更改,请告诉我们。还有一点:如果有人使用readUTF,另一方必须使用writeUTF 请提供一个完整的示例应用程序,运行两台我们可以复制、编译和运行的服务器。就像Jeroen说的,如果你想要一个答案,而不仅仅是猜测,我们需要一些东西来运行和调试。理想情况下,在GitHub上共享它,那么你很快就会找到解决问题的方法。@kriegaex问题是,这是我为Minecraft服务器制作的插件,所以我怀疑,除非您设置了必要的服务器,否则您是否能够实际运行代码……为什么不实现最小的客户机+服务器对,以便只测试套接字通信呢。这就是为什么我说的是MCVE而不是你原来的申请。刚好可以重现这个问题。在我看来,似乎你对套接字通信的发送端和接收端都有完全的控制权。弗兰克,你为什么要设立一个赏金,然后不向那些试图帮助你的人提供反馈?这不是一种浪费吗?嗯,在你的脑海中运行程序是问题的一部分,这正是我要求MCVE的原因。调试在计算机上运行的程序可以解决这个问题。我很高兴你解决了你的问题,如果你不理解它为什么会发生,这意味着随着下一次改变,它可能会再次发生。我真的很奇怪,如果你对一个结论性的答案不感兴趣或者不愿意为得到一个答案做出贡献,为什么你一开始就问这个问题,然后把悬赏放在上面。但是奥托,我不需要了解这个世界上的一切。Bro U使用input.readInt()-这是错误的!!!使用readUTF!!!
[02:45:24 INFO] Type: 1 // This is good!
[02:45:27 INFO] Type: 3 // This is good!
[02:45:43 INFO] Type: 16777216 // Huh??
[02:45:43 INFO] Type: 1280 // WHAT???
[02:45:43 INFO] Type: 256 // Insert confused guy meme here
[02:45:43 INFO] Type: 610548020
[02:45:43 INFO] Type: 1667643705
[02:45:43 INFO] Type: 925721650
[02:45:43 INFO] Type: 842018100
[02:45:43 INFO] Type: 878785581
[02:45:43 INFO] Type: 1647785059
[02:45:43 INFO] Type: 761477426
[02:45:43 INFO] Type: 825570148
[02:45:43 INFO] Type: 1647851062
public void sendPlayingUpdate(@NotNull Collection<UUID> players) throws IOException {
this.output.writeBoolean(true);
this.output.writeBoolean(false);
this.output.writeBoolean(false);
this.output.writeInt(5);
this.output.writeInt(players.size());
for (UUID player : players) {
this.output.writeUTF(String.valueOf(player));
}
// this.output.writeInt(4);
// this.output.writeInt(players.size());
// for (UUID uuid : players) {
// this.output.writeUTF(String.valueOf(uuid));
// }
this.output.flush();
}
01 00 00 00 00 00 05 00 00 00 01 00 24 [... load of hex ...]