java - Java套接字连接: receiving completely arbitrary integers from the Input Stream

标签 java sockets minecraft serversocket

我一直在学习Java中的套接字,以便在我正在开发的Minigame程序的两个单独的Java应用程序之间发送信息。目的是要拥有它,以便服务器A可以通过在switch语句中写入和读取int来告诉服务器B做某事。这是服务器端套接字的代码:

@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();
    }
}
当迷你游戏开始倒计时序列时,它将在迷你游戏实际开始时写入并刷新“1”到服务器端套接字,然后写入并刷新“3”。
// Tells Server A that the max players have been met
// and to start a countdown sequence for a Minigame.
public void sendStartUpdate(int gameKey) {
    try {
        this.output.writeInt(1);
        this.output.writeInt(gameKey);
        this.output.flush();
    } catch (IOException e) {
        e.printStackTrace();
    }
}
// Lets Server A know that the player is queued up for a Minigame
public void sendQueuingUpdate(@NotNull Collection<UUID> players) throws IOException {
    this.output.writeInt(3);
    this.output.writeInt(players.size());
    for (UUID player : players) {
        this.output.writeUTF(String.valueOf(player));
    }
    this.output.flush();
}
但是,由于某种原因,每当我运行该程序时,服务器都会首先收到预期的'1'和'3',然后又从服务器B接收到一系列非常长的整数。
[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
当迷你游戏结束并且程序通知服务器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();
}
注释掉的位是原始代码。如果我用未注释的代码替换它,它将给出所有那些任意大的整数。是否有其他应用程序可以通过某种方式连接到与套接字相同的端口并开始提供随机信息的方法?我只是看不到一个小的细微变化如何导致发送类似于1667643705的东西,这些整数确实让我想起了哈希码。
我很感激

最佳答案

时间戳指示第二和第三数据包之间有16秒的间隔。因此,很有可能不是第二个3数据包损坏了。您正在其他地方以未显示的代码发送格式错误的数据包。
数据为:

01 00 00 00  00 00 05 00  00 00 01 00  24 [... load of hex ...]
0x24$,但是可以是writeUTF的字符串长度-例如,两个UUID串联在一起。
我将开始测试语法分析代码,该语法代码可以解释格式代码的输出,而无需所有服务器内容。作为一个好处,这将需要更好地分解代码。

关于java - Java套接字连接: receiving completely arbitrary integers from the Input Stream,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65661837/

相关文章:

java - Selenium moveToElement 两次然后单击元素不起作用

java - 读取时客户端套接字出现问题

c - 在inet_pton 中使用什么地址?

java - Bukkit 前缀和后缀

java - Spring 中@Repository 和@RepositoryDe​​finition 有什么区别?

java - 带 where 子句的选择查询,其中选择基于参数值

java - 实现树可写类

java - 如何将switch语句中的条件返回到while?

java - 错误 getPlayer(args[0]);

c - 套接字在 send() 上失去连接