1

我有類:客戶端,服務器和後臺正在與Player類。 我真的不明白爲什麼我的客戶類與ObjectInputStream/ObjectOutputStream不工作的權利。的ObjectInputStream/ObjectOutputStream的工作不對

我在做什麼不好?我的錯誤在哪裏?

package Shooter2Dv27082013; 
public class Player implements Serializable{ 
.... 
public int x=10; 
public int y=10; 
.... } 

package Shooter2Dv27082013; 
public class Background extends JPanel implements ActionListener, Serializable { 
public int countCollisions=0; 
private int time = 20;      // 0.02s 
Timer mainTimer = new Timer(time, this); 
.... 
Player p = new Player(); ... } 

現在客戶端類:

package Shooter2Dv27082013; 


import javax.swing.*; 
import java.net.*; 
import java.io.*; 

public class Client { 
    public static void main(String[] ar) { 
     JFrame frame = new JFrame("D2 Shooter"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.setSize(1000, 520); 
     Background bg = new Background(); 
     frame.add(bg); 
     frame.setResizable(false); 
     frame.setVisible(true); 

     int serverPort = 6666; 
     String address = "127.0.0.1";/

     Player p = new Player(); 
     try { 
      InetAddress ipAddress = InetAddress.getByName(address); 
      System.out.println("Any of you heard of a socket with IP address " + address + " and port " + serverPort + "?"); 
      Socket socket = new Socket(ipAddress, serverPort); 
      System.out.println("Yes! I just got hold of the program."); 

      InputStream sin = socket.getInputStream(); 
      OutputStream sout = socket.getOutputStream(); 

      ObjectInputStream ois = new ObjectInputStream(sin); 
      ObjectOutputStream oos = new ObjectOutputStream(sout); 

      System.out.println("Streams are created. Let's try send these objects"); 
      System.out.println(); 


      System.out.println("P.x : "+bg.p.x); 
      while (true) { 
       oos.writeObject(bg.p); 
       oos.flush(); 
       oos.close(); 
       System.out.println("Player X: " + bg.p.x + " Player Y: " + bg.p.y); 
       p = (Player) ois.readObject(); 
       ois.close(); 
       System.out.println("New X: " + p.x + "New Y: "+p.y); 
       System.out.println("Looks like the server is pleased with us. Go ahead and enter more lines."); 
       System.out.println(); 
      } 

     } catch (Exception x) { 
      x.printStackTrace(); 
     } 
    } 
} 

它不會發送對象到服務器類,但它也隻字未提錯誤。

服務器類:

package Shooter2Dv27082013; 

import java.net.*; 
import java.io.*; 
public class Server { 
    public static void main(String[] ar) { 
     int port = 6666; 
     try { 
      ServerSocket ss = new ServerSocket(port); 
      System.out.println("Waiting for a client..."); 

      Socket socket = ss.accept(); 
      System.out.println("Got a client :) ... Finally, someone saw me through all the cover!"); 
      System.out.println(); 

      InputStream sin = socket.getInputStream(); 
      OutputStream sout = socket.getOutputStream(); 

      ObjectInputStream ois = new ObjectInputStream(sin); 
      ObjectOutputStream oos = new ObjectOutputStream(sout); 

      Player p = new Player(); 

      while(true) { 
       p = (Player) ois.readObject(); 
       System.out.println("The client just sent me this x: "+p.x+" y: "+p.y); 
       p.x=555; p.y=600; 
       System.out.println("I change it and now I'm sending it back..."); 
       oos.writeObject(p); 
       oos.flush(); 
       oos.close(); 
       System.out.println("Waiting for the next line..."); 
       System.out.println(); 
      } 
     } catch(Exception x) { x.printStackTrace(); } 
    } 
} 

回答

2

你在一個循環中關閉流。關閉後您不能使用流或任何資源。

+0

@Eldar這當然是與代碼中的問題,但僅靠固定這不會解決問題。發佈的代碼甚至沒有達到打印「流創建的時候,我們嘗試發送這些對象」,更不用說關閉任何東西了。 – EJP

5

您需要的ObjectInputStream之前構建的ObjectOutputStream,兩端。目前你有一個僵局。

需要移動環路以外關閉。

0

好吧,這是多麼對象流的工作和作品無處不在的解決方案。

對象流數據前面是一個4字節的「神奇」序列AC ED 00 05.在構建時,而不是在第一次讀取之前,ObjectInputStream將會查看這些數據。這是合乎邏輯的:在應用程序太遠之前,要確定它是一個合適的流。該序列在構建時由ObjectOutputStream進行緩衝,以便在第一次寫入時將其推入流中。此方法通常會導致緩衝情況下的複雜性或通過管道或套接字進行傳輸。幸運的是,所有這些問題的解決方案都非常簡單:

施工後立即沖洗ObjectOutputStream

ObjectOutputStream myStream = new ObjectOutputStream (anotherStream); 
myStream.flush(); 

在你的情況下,在客戶端和服務器應用程序。

+0

它不是'窺視[編輯]',它被*讀取,*處於阻塞模式;並且它不是'在第一次寫入時被推送到流上',它本身被寫入:如果它下面有一個緩衝流,它將被緩衝到第一個* flush()*,否則它立即出現。 – EJP