ObjectInputStream / ObjectOutputStream工作不对

我有类:Client,Server和Background正在使用Player类。 我真的不明白为什么带有ObjectInputStream / ObjectOutputStream Client类无法正常工作。

我做得不好? 哪里是我的错?

 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(); ... } 

现在Client类:

 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("Px : "+bg.px); while (true) { oos.writeObject(bg.p); oos.flush(); oos.close(); System.out.println("Player X: " + bg.px + " Player Y: " + bg.py); p = (Player) ois.readObject(); ois.close(); System.out.println("New X: " + px + "New Y: "+py); 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(); } } } 

它不会将Object发送到Server类,但它也没有说明错误。

服务器类:

 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: "+py); px=555; py=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(); } } } 

您正在循环关闭流。 关闭后,您无法使用流或任何资源。

您需要在两端的ObjectInputStream之前构造ObjectOutputStream。 目前你有一个僵局。

需要在循环外移动关闭。

好的,这就是对象流的工作方式以及适用于所有地方的解决方案。

对象流数据前面有一个4字节的“魔法”序列AC ED 00 05.一个ObjectInputStream将在构造时而不是在第一次读取之前查看该数据。 这是合乎逻辑的:人们希望确保它在应用程序中太过分之前是一个合适的流。 ObjectOutputStream在构造时缓冲该序列,以便在第一次写入时将其推送到流上。 此方法通常会导致缓冲情况的复杂性或通过管道或插槽传输。 幸运的是,对于所有这些问题,有一个简单有效的解决方案:

施工后立即冲洗ObjectOutputStream

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

在您的情况下,客户端和服务器应用程序。