4

私はKryonetの基本をカバーするこのYoutubeチュートリアルに従いました。

基本的にはKryonetHelloWorldであり、基本的なサーバーとクライアントをセットアップする方法を説明し、クライアントがサーバーにパケットを送信して非常に基本的な通信を行えるようにします。

ソースコードへのリンク。サーバーとクライアントの両方が同じパケットクラスを持っています。

サーバーを実行し、クライアントが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接続を閉じているようですが、よくわかりません。Kryonetの通信を許可するには、Windowsまたはルーターで何かを有効にする必要がありますか?

誰かが問題を見つけることができますか?前もって感謝します。

コマンドラインログにスペイン語で表示される行は、「既存の接続の中断がリモートホストによって強制されました」のようなものです。

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(); を呼び出すと、client.connect(); これを自動的に処理するクライアント スレッドがバックグラウンドで開始されます。

ユーザー入力 (While(true) get user input) を処理するための無限ループでクライアント スレッドをブロックしているため、クライアント スレッドがこれを行うのを妨げているようです。

代わりに、ユーザー入力を受け取る別のスレッドが必要です。クライアントの受信関数を実装する 1 つの方法 (おそらく最善ではない) を次に示します。

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 に答える
1

別のスレッドでクライアントを起動していないと思います。

「r122以降、クライアント更新スレッドはデーモンスレッドになり、初期化が完了するとすぐに子プロセスが閉じられました。」、解決策は「これを使用できますか? new Thread(client).start();」 .

たとえば、このようにクライアントを起動しているとしましょう

client.start();

むしろ使うべき

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

これが関連しているかどうかはわかりませんが(ソースコードへのリンクが機能していないため)、...

あなたが説明している問題は、サーバーを TCPおよびUDP 用に構成し、クライアントを TCP 経由でのみ接続する場合に発生する可能性があります。

ホスト検出を利用したいが、その後は TCP 接続のみが必要な場合は、「UDP 検出用に別のサーバーを実行する」ことをお勧めします。

于 2014-05-17T11:04:39.443 に答える