【问题标题】:Object lost data while sending through socket通过套接字发送时对象丢失数据
【发布时间】:2014-04-19 19:17:51
【问题描述】:

我试图在客户端和服务器之间来回发送一个对象,当它离开客户端时,所有数据都在那里,即 z = 6.0 但是当它到达服务器时,所有数据都被重置,即 z = 0.0

虽然它可能与我在对象中初始化变量有关,所以我没有初始化任何东西,我也添加了一个构造函数,但似乎没有任何作用。

对象:

public class PlayerData implements Serializable{

String name;
int id;
double x,y,z;
double rotation;

PlayerData(String name, double x, double y, double z) {
    this.name = name;
    this.x = x;
    this.y = y;
    this.z = z;
    id = -1;
}
}

客户端发送:

        Thread t = new Thread(){
        public void run() {
            while(true){
                try{
                    System.out.println("Client writing player z: " + player.z);
                    streamOut.writeObject(player);
                    streamOut.flush();
                }catch(Exception ioe){
                    System.out.println("Sending Error: "+ ioe.getMessage());
                }
            }
        }
    };
    t.start();      

服务器:

boolean done = false;
            while(!done) {
                //if(streamIn.available() > 0)
                try {
                    Object o = streamIn.readObject();
                    if(o instanceof PlayerData){
                        PlayerData recieved  = (PlayerData) o;
                        System.out.println("S: obj recieved z " + recieved.z);
                        for(int i = 0; i < serv.clientOut.size(); i++) {
                            serv.clientOut.get(i).writeObject(recieved);
                            serv.clientOut.get(i).flush();
                        }
                    }else 
                        System.out.println("Server: bad object");
                }
                catch(IOException e) {
                    done = true;
                }
            }

它会说

Client writing player z: -42.05979919433594
S: obj recieved z 0.0

【问题讨论】:

    标签: java sockets serialization objectinputstream objectoutputstream


    【解决方案1】:

    您通过序列化重复发送 same 对象 - 并且 ObjectOutputStream 注意到这一点,并将其解析为对同一对象的引用。

    如果您想在每次调用时有效地发送一个单独的对象,请将其添加到您的循环中:

    streamOut.reset();
    

    这样,每次您编写对象时,它都会将其写出来,就好像它以前从未见过一样(并且您将在另一边的每个readObject 调用中获得一个新对象)。当然,这意味着流会更大。我个人会考虑使用另一种序列化技术,例如 Protocol Buffers,但那是另一回事...

    【讨论】:

    • 你能给我指出一些关于协议缓冲区的资源吗?我是一名学生,正在尝试制作我的第一个多人游戏(我以前做过单人游戏)
    • @Duck:见protobuf.googlecode.com——当然,这只是一个选项。这是我碰巧最了解的一个:)
    • 谢谢,我会调查一下 :) 你的解决方案也有效(不能接受 4 分钟),所以也谢谢你
    猜你喜欢
    • 2012-03-13
    • 2017-09-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-21
    • 2014-01-11
    • 2022-01-15
    相关资源
    最近更新 更多