0

クラスの最後のプロジェクトは、マルチプレイヤーを含むゲームをまとめることです。それで私はJavaネットワーキングを理解しようとし始めました、そして私はちょっと立ち往生しています。

2つのゲームクライアントはそれぞれ、他のクライアントとの間でメッセージを送受信できる必要があります。

私がこれを処理すると思った方法は、独自のスレッドで実行されるNetworkServerオブジェクトとNetworkClientオブジェクトがあるということです。

メインのゲームアプリケーションから開始することを考えていましたが、最初にいくつかのテストを実行したかったので、このプロジェクトを設定しました。

NetworkClient:

import java.io.IOException;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.util.Timer;
import java.util.TimerTask;


public class NetworkClient extends Thread {

    Socket server;
    ObjectOutputStream out;
    Timer timer;


    public NetworkClient(String hostname, int port) throws IOException
    {
        server = new Socket(hostname, port);
        out = new ObjectOutputStream(server.getOutputStream());
        timer = new Timer();
        timer.schedule(new SendTask(),  0, 1*1000); 
    }

    public void sendData(Integer b) throws IOException {
        out.writeObject(b);
    }



    class SendTask extends TimerTask {
        Integer i = new Integer(1);

        public void run() {
            System.out.println("Client: Sending Integer: " + i.toString());
            try {
                sendData(i);
                i = new Integer(i.intValue()+1);
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        } // run()
    } // class SendTask

}

NetworkServer:

import java.io.IOException;
import java.io.ObjectInputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketTimeoutException;


public class NetworkServer extends Thread {

    private ServerSocket serverSocket;
    private Socket client;
    private Integer i;
    private ObjectInputStream in;

    public NetworkServer(int port) throws IOException
    {
       serverSocket = new ServerSocket(port);
       //serverSocket.setSoTimeout(10000);
    }

    public void run()
    {
       try {
        System.out.println("Waiting for client on port " + serverSocket.getLocalPort() + "...");  
        client = serverSocket.accept();           
        System.out.println("Just connected to " + client.getRemoteSocketAddress());
        in = new ObjectInputStream(client.getInputStream());
        } catch (IOException e2) {
            // TODO Auto-generated catch block
            e2.printStackTrace();
        }

       while(true)
       {

          try
          {
             i = (Integer) in.readObject();
             System.out.println("Server: Received the integer: " + i.toString());
          }
          catch(SocketTimeoutException s)
          {
             System.out.println("Socket timed out!");
             break;
          }
          catch(IOException e)
          {
             e.printStackTrace();

             try { client.close();} catch (IOException e1) {}

             break;
          } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
       }
    }

}

ネットワーク(これを試してテストするために使用しているもの):

import java.io.IOException;


public class Network {

    NetworkClient client;
    NetworkServer server;

    public Network() throws IOException {
        server = new NetworkServer(6066);
        server.start();

        client = new NetworkClient("192.168.1.196", 6066);
        client.start();
    }

    public static void main(String [] args)
    {
       try
       {
          Network n = new Network();
       }catch(IOException e)
       {
          e.printStackTrace();
       }
    }

}

クライアントからサーバーへのデータ送信を容易にするためにタイマーがあります。これは通常、ゲームによって実行されますが、テストしているため、何らかの方法で送信する必要がありました。

クライアントとサーバーが相互に通信している場所でこれを実行すると、送信済みメッセージと受信済みメッセージの両方が表示されます。

それをラップトップに置いて(そしてNetworkClientのIPをデスクトップに一致するように変更し、その逆も同様に)両方の場所で実行すると、デスクトップのクライアントはラップトップのサーバーに送信しますが、クライアントはラップトップはデスクトップ上のサーバーに送信しません。

また、実行中のある時点で、動作中のクライアント/サーバー接続は継続されますが、そのクライアントの接続がピアによってリセットされるという例外が発生します。

だから、私の質問は、なぜそれが一方向では機能するが双方向では機能しないのか誰かが知っていると思いますか?

修繕!!

編集:ああ、私はそれを理解しました。これは、2台のサーバーを起動するタイミングと関係がありました。

ネットワークを次のように変更しました:

import java.io.IOException;


public class Network {

    NetworkClient client;
    NetworkServer server;

    public Network() throws IOException {
        startServer();

        startClient();
    }

    private void startServer() throws IOException {
        server = new NetworkServer(6066);
        server.start();
    }

    private void startClient(){
        boolean isConnected = false;
        while (!isConnected) {
            try {
                client = new NetworkClient("192.168.1.196", 6066);
            } catch (IOException e) {
                // TODO Auto-generated catch block
                //e.printStackTrace();
                continue;
            }
            isConnected = true;
        }
        client.start();
    }

    public static void main(String [] args)
    {
       try
       {
          Network n = new Network();
       }catch(IOException e)
       {
          e.printStackTrace();
       }
    }

}
4

1 に答える 1

0

ファイアウォールを編集します。java.exe でインバウンドとアウトバウンドのトラフィックが有効になっていることを確認してください。また、ファイアウォールにポート 6066 のルールを追加します。

于 2012-04-14T01:41:02.523 に答える