4

我遵循了这个 Youtube 教程,涵盖了 Kryonet 的基础知识。

基本上它是一个 Kryonet Hello World,它解释了如何设置一个基本的服务器和一个客户端,允许客户端向服务器发送数据包并进行非常基本的通信。

源代码的链接。服务器和客户端都具有相同的数据包类。

我可以让服务器运行,客户端要求 IP 连接。但是,当我输入 IP 时,客户端在连接后立即终止。

客户端输出:

00:03  INFO: Connecting: /127.0.0.1:54555
00:03  INFO: [kryonet] Connection 1 connected: /127.0.0.1
00:03  INFO: [CLIENT] You have connected.
BUILD SUCCESSFUL (total time: 3 seconds)

服务器命令行日志:

00:00  INFO: [kryonet] Server opened.
00:04 DEBUG: [kryonet] Port 54555/TCP connected to: /127.0.0.1:53217
00:04 DEBUG: [kryo] Write: RegisterTCP
00:04  INFO: [kryonet] Connection 1 connected: /127.0.0.1
00:04  INFO: [SERVER] Someone has connected.
00:04 DEBUG: [kryonet] Connection 1 update: Se ha forzado la interrupcion de una
 conexion existente por el host remoto
00:04  INFO: [SERVER] Someone has disconnected.
00:04  INFO: [kryonet] Connection 1 disconnected.

似乎系统关闭了 TCP 连接,但我真的不知道。我必须在 Windows 或/和路由器中启用某些东西以允许 Kryonet 通信吗?

有人能发现问题吗?提前致谢。

命令行日志中以西班牙语显示的行类似于“远程主机已强制中断现有连接”。

在 user1816380 建议后编辑:

大多数时候它仍然显示原始错误,但有时您会看到:

00:00  INFO: [kryonet] Server opened.
00:07 DEBUG: [kryonet] Port 54555/TCP connected to: /127.0.0.1:50787
00:07 DEBUG: [kryo] Write: RegisterTCP
00:07  INFO: [kryonet] Connection 1 connected: /127.0.0.1
00:07  INFO: [SERVER] Someone has connected.
00:07 DEBUG: [kryo] Read: Packet0LoginRequest
00:07 DEBUG: [kryonet] Connection 1 received TCP: Packet0LoginRequest
00:07 DEBUG: [kryo] Write: Packet1LoginAnswer
00:07 DEBUG: [kryonet] Connection 1 sent TCP: Packet1LoginAnswer (6)
00:07 DEBUG: [kryonet] Connection 1 update: Se ha forzado la interrupcion de una
 conexion existente por el host remoto
00:07  INFO: [SERVER] Someone has disconnected.
00:07  INFO: [kryonet] Connection 1 disconnected.
4

5 回答 5

6

为了让您的客户端保持连接,它需要发送和接收 KeepAlive 数据包。当你调用 client.start(); 客户端.connect(); 一个客户端线程在后台启动,它会自动为您处理这个问题。

似乎您正在阻止客户端线程执行此操作,因为您使用无限循环阻止它来处理用户输入(而(true)获取用户输入)。

相反,您应该有一个单独的线程来接受用户输入。这是实现客户端接收功能的一种方法(可能不是最好的):

public void received(Connection c, Object o) {
    System.out.println("received something");
    if (o instanceof Packet1LoginAnswer){

        boolean answer = ((Packet1LoginAnswer) o).accepted;

        if (answer) {
          System.out.println("Please enter your message for server");
            new Thread("Get User Input") {
                public void run () {
                    try {

                      if (ChatClient.scanner.hasNext()){
                        Packet2Message mpacket = new Packet2Message();
                        mpacket.message = ChatClient.scanner.nextLine();
                        client.sendTCP(mpacket);
                        System.out.println("Please enter another message");
                      }

                    } catch (Exception ex) {
                        ex.printStackTrace();
                        System.exit(1);
                    }
                }
            }.start();

        } else {
              System.out.println("Answer is false");
          c.close();
        }
    }

    if (o instanceof Packet2Message){
        String message = ((Packet2Message) o).message;
        Log.info(message);
    }
}

我还注意到您使用 Log.info()。这仅在您使用 Kryonet 的调试版本时才有效。最好只使用标准输出函数。

于 2012-11-11T18:04:03.703 回答
2

我只是遇到了同样的问题,我尝试了所有其他答案,但没有奏效。结果我在 TCP 端口1941和 UDP 端口上托管了一个服务器1942 但是我的客户端正在连接到一个带有 TCP 端口的服务器1941(忽略 UDP 端口)。像这样添加 UDP 端口为我解决了这个问题:

client.connect(5000, address, 1941, 1942);
于 2015-11-17T20:44:24.620 回答
1

我认为您没有在单独的线程中启动客户端。

“从 r122 开始,客户端更新线程被制成守护线程,导致子进程在完成初始化后立即关闭。”,解决方案是“也许你可以使用这个?new Thread(client).start();” .

所以让我们说例如你正在像这样开始你的客户

client.start();

而你应该使用

new Thread(client).start();
于 2015-05-15T15:10:40.637 回答
0

相同的问题和行为可能是由于使用了最新版本的 KryoNet 2.20。例如,当使用 kryonet-2.12 时,问题很可能会得到解决。

所以尝试使用 kryonet-2.12 而不是 kryonet-2.20,这个例子应该可以工作 ;-)

于 2013-06-26T12:30:46.703 回答
0

我不确定这是否相关(因为您的源代码链接不再有效)但是......

如果您将服务器配置为 TCPUDP,但随后让您的客户端通过 TCP 连接,则可能会出现您所描述的问题。

如果您想利用主机发现但此后只需要 TCP 连接,那么建议您“为 UDP 发现运行单独的服务器”

于 2014-05-17T11:04:39.443 回答