Avatar billede bentblod Nybegynder
12. januar 2005 - 17:03 Der er 10 kommentarer og
1 løsning

Netværks programmering i javaspil

Hej, er godt igang med at lave et spil i java som man kan game over netværk. Folk kan sagtens joine og køre rundt. Men ligepludselig efter noget tid, siger den:

java.lang.NullPointerException

    at tankzServer.NetvaerksServer$ClientHandler.run(NetvaerksServer.java:113)

som jeg nok skal vise hvad er... Men nogen der ved hvad der kan være galt med det? Prøver at copy paste koden og mærkere stedet som den henviser til med ------------------, Jeg har gjort sådan at klienten sender kommandoer til serveren hvert 100 milisec, så burde ikke være fordi den får for mange kommandoer på en gang. Forstår det ikke :( Plz nogen der kan hjælpe??

                      netværks serveren:


package tankzServer;

import java.io.*;
import java.net.*;
import java.util.Vector;

public class NetvaerksServer {

  private static ServerSocket servSocket;
  private static final int PORT = 7777;
  private static Vector klienter = new Vector();
  private static BufferedReader in;
  private static PrintWriter out;

  private SpillerTjek[] st = {new SpillerTjek(0,false),
  new SpillerTjek(1,false),
  new SpillerTjek(2,false),
  new SpillerTjek(3,false),
  new SpillerTjek(4,false),
  new SpillerTjek(5,false),
  new SpillerTjek(6,false),
  new SpillerTjek(7,false)
  };


  public NetvaerksServer() {
  }

  public void sendBeskedTilTraad(Tank tank) {
    for (int i = 0; i < klienter.size(); i++) {
      ClientHandler h = (ClientHandler) klienter.elementAt(i);
      h.sendBesked(tank);
    }
  }

  public void startNetvaerkforbindelsen() throws IOException {
    try {
      servSocket = new ServerSocket(PORT);
      System.out.println("Port er åbnet");
    }
    catch (IOException ex) {
      System.out.println("\nUnable to set up port!");
      System.exit(1);
    }

    do {
      Socket client = servSocket.accept();
      System.out.println("\nNew client accepted.\n");
      for (int i = 0; i < st.length; i++) {
        if (!st[i].isOptaget()) {
          st[i].setOptaget(true);
          ClientHandler handler = new ClientHandler(client,st[i].getSpiller());
          klienter.addElement(handler);
          handler.start();
          System.out.println("Klienten har fået spiller nr: " + st[i].getSpiller());
          break;
        }
      }

    }
    while (true);
  }

  private class ClientHandler
      extends Thread {
    private Socket client;
    private BufferedReader in;
    private PrintWriter out;
    private String besked = "";
    private String option = "";
    private int spiller= 0;
    private int spiller2=0;
    private String player="";
    private Tank[] tanks = {new Tank(100,100,0,0),
    new Tank(200,100,0,1),
    new Tank(300,100,0,2),
    new Tank(400,100,0,3),
    new Tank(500,100,0,4),
    new Tank(600,100,0,5),
    new Tank(700,100,0,6),
    new Tank(800,100,0,7)
    };


    public ClientHandler() {

    }

    public ClientHandler(Socket socket, int spilleren) {
      client = socket;
      this.spiller2 = spilleren;
      try {
        in = new BufferedReader(new InputStreamReader(client.getInputStream()));
        out = new PrintWriter(client.getOutputStream(), true);
        out.println("Connected");
        out.println(spilleren);
      }
      catch (IOException ex) {
        ex.printStackTrace();
      }
    }

    /**
    * Run metode som bliver startet af start
    */
    public void run() {
      try {
        do {
          option = in.readLine();
          System.out.println("spiller: " + spiller2);

---------------------HER!!!-------------------------------

          if (option.equals("left")) {
            tanks[spiller] = ServerController.getInstance().moveLeft(tanks[spiller2]);
            sendBeskedTilTraad(tanks[spiller]);
          }
          else if (option.equals("right")) {
            tanks[spiller] = ServerController.getInstance().moveRight(tanks[spiller2]);
            sendBeskedTilTraad(tanks[spiller]);
          }
          else if (option.equals("up")) {
            tanks[spiller] = ServerController.getInstance().moveUp(tanks[spiller2]);
            sendBeskedTilTraad(tanks[spiller]);
          }
          else if (option.equals("down")) {
            tanks[spiller] = ServerController.getInstance().moveDown(tanks[spiller2]);
            sendBeskedTilTraad(tanks[spiller]);
          }


        }
        while (!besked.equals("QUIT"));
      }
      catch (IOException ex) {
        ex.getStackTrace();
      }

      finally {
        try {
          if (client != null) {
            System.out.println("Closing down connection...");
            st[spiller2].setOptaget(false);
            klienter.removeElement(this);
            client.close();
            System.out.println("size: " + klienter.size());
          }
        }
        catch (IOException ex) {
          ex.printStackTrace();
        }
      }
    }

    public void sendBesked(Tank tank) {
      out.println(tank.getSpiller());
      out.println(tank.getAngle());
      out.println(tank.getX());
      out.println(tank.getY());
      out.flush();
    }
  }

  /**
  * Singleton
  * @return Returnerer den eneste instans af klassen.
  */
  public static NetvaerksServer getInstance() {
    if (netvaerksServer == null)
      netvaerksServer = new NetvaerksServer();
    return netvaerksServer;
  }

  /**
  * Singleton, indeholder en instans af sig selv, eller null.
  */
  public static NetvaerksServer netvaerksServer = null;

}


                        Netværks klienten:


package tankz;

import java.io.*;
import java.net.*;
import java.util.Vector;
import java.util.StringTokenizer;


public class NetvaerksKlient {
  public NetvaerksKlient() {
  }

  private static InetAddress host;
  private static final int PORT = 7777;
  private static String navn = "";
  public static Socket link;
  private static BufferedReader in;
  private static PrintWriter out;

  public void connect(String host1) {
    String response = "";
    try {
      host = InetAddress.getByName(host1);
      link = new Socket(host, PORT);
      in = new BufferedReader(new InputStreamReader(link.getInputStream()));
      out = new PrintWriter(link.getOutputStream(), true);
      response = in.readLine();
    }
    catch (IOException ex) {
      response = "Not connected";
    }
    System.out.println("" + response);
    if (response.equals("Connected")) {
      try {
        int spiller = Integer.parseInt(in.readLine());
        Controller.getInstance().setSpillerensNr(spiller);
      }
      catch (Exception ex) {
        System.err.println("Fejl i at hente spillerens nr: " + ex.getMessage());
      }
      ClientThread ct = new ClientThread(link);
      ct.start();
    }
  }

  public void disconnect() {
    try {
      if (link != null) {
        out.println("QUIT");
        link.close();
        System.out.println("Disconnected");
        System.exit(1);
      }
    }
    catch (IOException ex) {
      ex.printStackTrace();
    }
  }


  public void sendBesked(String option, int spiller) {
    out.println(option);
    out.flush();
  }


  private class ClientThread
      extends Thread {
    private Socket client;
    private BufferedReader in;
    private PrintWriter out;
    private String option = "";

    private Tank[] tanks = {new Tank(0,0,1,0),
    new Tank(100,100,1,1),
    new Tank(200,200,1,2),
    new Tank(300,300,1,3),
    new Tank(400,400,1,4),
    new Tank(500,500,1,5),
    new Tank(600,600,1,6),
    new Tank(700,700,1,7)
    };



    /**
    * Constructor
    */
    public ClientThread() {

    }
    /**
    * Constructor
    * @param socket
    */
    public ClientThread(Socket socket) {
      client = socket;
      try {
        in = new BufferedReader(new InputStreamReader(client.getInputStream()));
        out = new PrintWriter(client.getOutputStream(), true);
      }
      catch (IOException ex) {
        ex.printStackTrace();
      }
    }

    /**
    * Run metode i tråden, håndtere alle input fra serveren
    */
    public void run() {
      while (true) {
        try {
          int spiller = Integer.parseInt(in.readLine());
          tanks[spiller].setAngle(Double.parseDouble(in.readLine()));
          tanks[spiller].setX(Integer.parseInt(in.readLine()));
          tanks[spiller].setY(Integer.parseInt(in.readLine()));
          Controller.getInstance().opdaterTank(tanks[spiller]);
        }
        catch (Exception ex) {
          System.err.println("FEJL!!! " + ex.getMessage());
          disconnect();
        }
      }
    }
  }

  /**
  * Singleton
  * @return Returnerer den eneste instans af klassen.
  */
  public static NetvaerksKlient getInstance() {
    if (netvaerksKlient == null)
      netvaerksKlient = new NetvaerksKlient();
    return netvaerksKlient;
  }

  /**
  * Singleton, indeholder en instans af sig selv, eller null.
  */
  public static NetvaerksKlient netvaerksKlient = null;

}
Avatar billede dsj Nybegynder
12. januar 2005 - 17:58 #1
Hvilken linie er nr. 113?
Avatar billede dsj Nybegynder
12. januar 2005 - 18:02 #2
Hvis der er tale om 'if (option.equals("left")) {', er det fordi option ikke er initialiseret, hvilket igen skyldes at in.readLine(); returnerer null.

Fra Javadoc'en om BufferedReader.readLine():

Returns:
A String containing the contents of the line, not including any line-termination characters, or null if the end of the stream has been reached.

Hvis option altså er null, er netværksforbindelsen af en eller anden årsag blevet afbrudt.
Avatar billede dsj Nybegynder
12. januar 2005 - 18:02 #3
Og det skulle have været et svar.
Avatar billede bentblod Nybegynder
12. januar 2005 - 21:48 #4
Men hvis den siger option = null hvorfor bryder den så ud og smider klienten af? hvorfor ignorere den det ikke bare? det er jo en if sætning som spørger om den er "left".
Avatar billede bentblod Nybegynder
12. januar 2005 - 21:48 #5
Men hvad gør jeg egentlig ved det?
Avatar billede dsj Nybegynder
12. januar 2005 - 21:54 #6
Metoden left() kaldes på option der er null, hvilket giver fejlen.

Du bør gøre som følgende:


          if (option == null{
            throw new IOException("End of stream);

          } else if (option.equals("left")) {
            tanks[spiller] = ServerController.getInstance().moveLeft(tanks[spiller2]);
            sendBeskedTilTraad(tanks[spiller]);
          } ...osv.

Altså kontrollere hvorvidt option er lig null som det absolut første, hvilket får serveren til at bryde ud af while-løkken og rydde op efter klienten.
Avatar billede dsj Nybegynder
12. januar 2005 - 21:55 #7
Og lige en rettelse:

          if (option == null) {
            throw new IOException("End of stream");
          } ...
Avatar billede bentblod Nybegynder
12. januar 2005 - 22:15 #8
Ok jeg tester det lige og kommer tilbage når jeg har fundet ud af om den stadig gør det :) Men mange tak indtil videre hvertfald :)
Avatar billede dsj Nybegynder
12. januar 2005 - 22:22 #9
Men hold op hvor jeg også vrøvler... rettelse:

Metoden equals("left") kaldes på option der er null, hvilket giver fejlen.
Avatar billede bentblod Nybegynder
12. januar 2005 - 22:35 #10
Ok nu virker serveren hvertfald som den skal, men var ude for at klienten også kom med en fejl, fik så ikke gemt fejlmeddelelsen :( og har nu prøvet 15 min uden fejlen kom, så jeg skriver bare så snart jeg har fanget den :)
Avatar billede bentblod Nybegynder
15. januar 2005 - 04:16 #11
Nårmen er ikke støt på fejlen endnu. Så du får bare dine points:) Mange tak for hjælpen :D
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester