从服务器发送映射对象到客户端,ObjectOutputStream错误

时间:2014-11-10 04:28:10

标签: java object client server objectoutputstream

我是使用ObjectOutputStream的新手。我试图从我的游戏服务器向我的客户端发送一个地图对象。但是,当我尝试发送我的地图对象时,服务器会抛出一个java.io.notserializableexception。我不熟悉调试这些问题。我很感激一些专家的帮助。 下面我将首先获得控制台输出,然后是服务器代码,然后是客户端代码。

The DPServer is now accepting connetions
Client Socket[addr=/192.168.0.11,port=65435,localport=30480] has connected!
Client: new DPClient
Server: Do I try and send a map?
java.io.NotSerializableException: dark_project.map.MazeCell
    at java.io.ObjectOutputStream.writeObject0(Unknown Source)
    at java.io.ObjectOutputStream.writeArray(Unknown Source)
    at java.io.ObjectOutputStream.writeObject0(Unknown Source)
    at java.io.ObjectOutputStream.writeArray(Unknown Source)
    at java.io.ObjectOutputStream.writeObject0(Unknown Source)
    at java.io.ObjectOutputStream.writeObject(Unknown Source)
    at dark_project.server.DPServer.sendMap(DPServer.java:139)
    at dark_project.server.DPServer.run(DPServer.java:111)
    at dark_project.server.DPServer.main(DPServer.java:161)
Could not get input stream from Thread[Thread-0,5,main] say something helpful.

服务器

public class DPServer 
{
  private static final boolean DEBUG = false;
  private static final int DPSERVER_PORT = 30480; 
  private static final int DPSERVER_THROTTLE = 250;
  private static Map map; //contains the map
  private static int mapDimensions;
  private static MazeCell[][] mazeCells;
  private ServerSocket serverSocket;
  private InetAddress hostAddress;
  private Socket socket;
  private ArrayList<DPClient> players = new ArrayList<DPClient>();
  private static BufferedReader bufferedReader;
  private static String inputLine;
  private static boolean mapSent = true;

  /**
   * DPServer()
   * Basic Constructor 
   */
  public DPServer()
  {
    // Attempt to get the host address
    try
    {
      hostAddress = InetAddress.getLocalHost();
    }
    catch(UnknownHostException e)
    {
      if (DEBUG)System.out.println("Could not get the host address!");
      return;
    }
    //Outputs host address!
    if (DEBUG) System.out.println("Server host address is: " + hostAddress);
    //Attempt to create server socket
    try
    {
      serverSocket = new ServerSocket(DPSERVER_PORT,0,hostAddress); //<< 0 means default 
    }
    catch(IOException e)
    {
      if (DEBUG) System.out.println("Could not open server socket!");
      return;
    }
    //Socket was created! Yay.
    System.out.println("Socket " + serverSocket + " created.");
  }

  /**
   * run()Could not get input stream from Thread
   * Starts the server so it can begin accepting client connections.
   */
  public void run()
  {
    System.out.println("The DPServer is now accepting connetions");
    while(true)
    {
      // First looks to remove disconnected players
      for(int i = 0; i < players.size(); i++) 
      {
        // If player returns a connection == false then player is purged
        if(!players.get(i).isConnected())
        {
          System.out.println(players.get(i) + " purge, connection was dropped!");
          players.remove(i);
        }
      }
      // Get a client trying to connect
      try
      {
        socket = serverSocket.accept();
        mapSent = false; //need to make sure map sent is false here for when a new client connects
      }
      catch(IOException e)
      {
        if (DEBUG) System.out.println("Could not find a client trying to connect. :(");
      }
      // Client has connected! Everyone is happy.
      System.out.println("Client " + socket + " has connected!");
      // Add client as a player to arraylist.
      players.add(new DPClient(socket));
      // Send Client Map
      try
      {
        if (mapSent == false)
        {
          System.out.println("Server: Do I try and send a map?");
          sendMap(socket);
          mapSent = true;
        }
      } 
      catch (IOException e)
      {
        e.printStackTrace();
      }
      // Sleep
      try
      {
        Thread.sleep(DPSERVER_THROTTLE);
      }
      catch(InterruptedException e)
      {
        System.out.println("DPServer has been interrupted!");
      }
    }
  }

  /**
   * This sends the map to the client.
   * @param client
   * @throws IOException
   */
  private void sendMap(Socket client) throws IOException
  {
    ObjectOutputStream out = new ObjectOutputStream(client.getOutputStream());
    out.writeObject(mazeCells); //error here
    out.close();
    out.flush();
  }

  public static void main(String[] args)
  {
    int i = 0, j = 0;
    //create map then run server
    map = new Map();
    mapDimensions = map.getCellList().length;
    mazeCells = new MazeCell[mapDimensions][mapDimensions];
    //creates a hard copy of the maze
    for(i = 0; i < map.getCellList().length; i++)
    {
      for (j = 0; j < map.getCellList().length; j++)
      {
        mazeCells[i][j] = map.getCellList()[i][j];
        //System.out.println(map.getCellList()[i][j]);
      }
    }
    DPServer gameServer = new DPServer();
    gameServer.run();
  }
}

客户端

@SuppressWarnings("unused")
public class DPClient
{
  private static final int USER_THROTTLE = 250; // arbitrary number, will need
                                                // to revisit this.
  private Socket socket;
  private boolean connected;
  private InPort inport;
  private Map map;
  private static int mapDimensions;
  private static MazeCell[][] mazeCells;

  private class InPort extends Thread
  {
    private ObjectInputStream inFromServer;

    public void run()
    {
      try
      {
        inFromServer = new ObjectInputStream(socket.getInputStream());
        try
        {
          System.out.println("Client: Server says "
              + inFromServer.readObject().toString());
        } catch (ClassNotFoundException e)
        {
          e.printStackTrace();
        }
      } catch (IOException e)
      {
        System.out.println("Could not get input stream from " + toString()
            + " say something helpful.");
        return;
      }
      // connected!!! :) everyone is happy now
      System.out.println(socket + " has connected input stream!!!!!!!!!!!!!");
      // client should do listening and send info to server here
      while (true)
      {
        try
        {
          Thread.sleep(USER_THROTTLE);
        } catch (Exception e)
        {
          System.out.println(toString() + " has input stream interrupted.");
        }
      }

    }
  }

  /**
   * DPClient() Basic Constructor Creates a new client with the socket form the
   * newly connected client.
   * 
   * @param newSocket
   *          The socket from the connected client.
   */
  public DPClient()
  {
    Socket newSocket = obtainSocket();
    if (newSocket == null)
    {
      System.out.println("Error Detected");
      System.exit(-1);
    }
    DPClient ClientAndSocket = new DPClient(newSocket);
  }

  /**
   * DPClient(newSocket) Overloaded Constructor Constructor that creates a new
   * client with the socket form the newly connected client.
   * 
   * @param newSocket
   *          The socket from the connected client.
   */
  public DPClient(Socket newSocket)
  {
    System.out.println("Client: new DPClient");
    socket = newSocket;
    connected = true;
    inport = new InPort();
    inport.start();
  }

  /**
   * isConnected() Returns the connection status of the client.
   * 
   * @return the connection status of the client true or false
   */
  public boolean isConnected()
  {
    return connected;
  }

  /**
   * purge() Purges this client from the connection! Sets connected = false
   */
  public void purge()
  {
    try
    {
      System.out.println("You have been purged.");
      connected = false;
      socket.close();
    } catch (IOException e)
    {
      System.out.println("Could not purge " + socket + "!");
    }
  }

  /**
   * toString() Returns the String representation of this user. Helper Method
   * 
   * @return A string representation
   */
  public String toString()
  {
    return new String(socket.toString());
  }

  /**
   * obtainSocket() Helper Function
   * 
   * @return socket. clientSocket used to connect to a network.
   */
  public Socket obtainSocket()
  {
    InetAddress hostAddress = null;
    Socket clientSocket;
    String input = null;
    try
    {
      input = (String) JOptionPane.showInputDialog(null,
          "Please enter server address", "Server Selection");

      hostAddress = InetAddress.getLocalHost();
    }

    catch (UnknownHostException e)
    {
      System.out.println("Could not get the host address!");
      return null;
    }
    // Outputs host address!
    System.out.println("Server host address is: " + hostAddress);
    // Create new socket
    try
    {
      if (input == null)
        clientSocket = new Socket(hostAddress, 30480);
      else
        clientSocket = new Socket(input, 30480);
    } catch (UnknownHostException e)
    {
      e.printStackTrace();
      return null;
    } catch (IOException e)
    {
      System.err.println("testClient Error: Could not open connection to "
          + "localhost" + " on port " + "30480");
      e.printStackTrace();
      return null;
    }
    return clientSocket;
  }
  public static void main (String[] args)
  {
    DPClient testClient = new DPClient();
    //MainGameLoopTest.runGame();
  }
}

1 个答案:

答案 0 :(得分:0)

我还没有真正阅读过您的代码,但错误听起来非常清楚。您尝试发送的地图包含dark_project.map.MazeCell的实例,此类不可序列化。您要通过网络发送的所有类(或在文件中存储原始类)需要实现Serializable:)