Java ObjectInputStream/ObjectOutputStream工作不正常
我有几个类:客户端、服务器和后台正在使用Player类。 我真的不明白为什么我的ObjectInputStream/ObjectOutputStream客户端类不能正常工作 我做了什么坏事?我的错在哪里Java ObjectInputStream/ObjectOutputStream工作不正常,java,sockets,serialization,objectinputstream,objectoutputstream,Java,Sockets,Serialization,Objectinputstream,Objectoutputstream,我有几个类:客户端、服务器和后台正在使用Player类。 我真的不明白为什么我的ObjectInputStream/ObjectOutputStream客户端类不能正常工作 我做了什么坏事?我的错在哪里 package Shooter2Dv27082013; public class Player implements Serializable{ .... public int x=10; public int y=10; .... } package Shooter2Dv27082013;
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(); }
}
}
您正在循环中关闭流。关闭流或任何资源后,您不能使用它。您正在循环中关闭流。关闭流或任何资源后,您都不能使用它。您需要在ObjectInputStream之前在两端构造ObjectOutputStream。现在你陷入了僵局
您还需要将闭包移到循环之外。您需要在两端的ObjectInputStream之前构造ObjectOutputStream。现在你陷入了僵局
您还需要将闭包移到循环之外。好的,这就是对象流的工作方式,以及适用于任何地方的解决方案 对象流数据前面有一个4字节的“神奇”序列AC ED 00 05。ObjectInputStream将在构造时而不是在第一次读取之前查看此数据。这是合乎逻辑的:在应用程序中走得太远之前,需要确保它是正确的流。序列在构造时由ObjectOutputStream缓冲,以便在第一次写入时将其推送到流上。这种方法通常会导致缓冲情况或通过管道或套接字传输的复杂性。幸运的是,所有这些问题都有一个简单而有效的解决方案: 构建后立即刷新ObjectOutputStream
ObjectOutputStream myStream = new ObjectOutputStream ( anotherStream );
myStream.flush();
在客户端和服务器应用程序中都是这样。好的,这就是对象流的工作方式和在任何地方都能工作的解决方案 对象流数据前面有一个4字节的“神奇”序列AC ED 00 05。ObjectInputStream将在构造时而不是在第一次读取之前查看此数据。这是合乎逻辑的:在应用程序中走得太远之前,需要确保它是正确的流。序列在构造时由ObjectOutputStream缓冲,以便在第一次写入时将其推送到流上。这种方法通常会导致缓冲情况或通过管道或套接字传输的复杂性。幸运的是,所有这些问题都有一个简单而有效的解决方案: 构建后立即刷新ObjectOutputStream
ObjectOutputStream myStream = new ObjectOutputStream ( anotherStream );
myStream.flush();
在您的客户端和服务器应用程序中。@Eldar这肯定是代码的问题,但仅解决此问题无法解决问题。发布的代码甚至没有达到创建打印流的程度。让我们试着发送这些对象,更不用说关闭任何东西了。@Eldar这当然是代码的问题,但仅修复它并不能解决问题。发布的代码甚至没有达到创建打印流的程度。让我们试着发送这些对象,更不用说关闭任何东西了。它不是“peek[ed]”,而是在阻塞模式下读取的;而且它不是“第一次写入时推送到流上”,它本身就是写入的:如果下面有缓冲流,它将被缓冲到第一次刷新,否则它会立即出现。它不是“peek[ed]”,而是在阻塞模式下读取的;而且它不是“在第一次写入时被推送到流上”,它本身就是被写入的:如果在它下面有缓冲流,它将被缓冲直到第一次刷新,否则它会立即出现。