【问题标题】:ObjectInputStream/ObjectOutputStream work not rightObjectInputStream/ObjectOutputStream 工作不正常
【发布时间】:2013-08-29 23:47:47
【问题描述】:

我有类:客户端、服务器和背景正在使用 Player 类。 我真的不明白为什么我的带有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();
        }
    }
}

它不会将 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: "+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(); }
    }
}

【问题讨论】:

    标签: java sockets serialization objectinputstream objectoutputstream


    【解决方案1】:

    你需要在ObjectInputStream之前,在两端构造ObjectOutputStream。目前你有一个死锁。

    需要将闭包移到循环之外。

    【讨论】:

      【解决方案2】:

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

      【讨论】:

      • @Eldar 这肯定是代码的问题,但单独解决这个问题并不能解决问题。发布的代码甚至没有打印“流已创建。让我们尝试发送这些对象”,更不用说关闭任何东西了。
      【解决方案3】:

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

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

      构建后立即刷新ObjectOutputStream

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

      在您的客户端和服务器应用程序中。

      【讨论】:

      • 它不是'peek[ed]',它是读取,处于阻塞模式;并且它不是“在第一次写入时推送到流上”,它本身是被写入的:如果它下面有一个缓冲流,它会被缓冲直到第一个 flush() ,否则它会立即出现.
      猜你喜欢
      • 2015-07-17
      • 2015-01-05
      • 2014-10-18
      • 2011-04-27
      • 2019-06-07
      • 2017-09-07
      • 2018-11-06
      • 2011-07-18
      • 1970-01-01
      相关资源
      最近更新 更多