繁体   English   中英

通过套接字可序列化传输对象

[英]Transferring Object over Sockets-Serializable

这是我编写的用于传输对象pm(类PM)的代码,该对象包含任何对象vm(类VM)通过套接字。

public class PM implements Serializable{
    private static final long serialVersionUID=1L;

    VM vm[]=new VM[10];

    //IP of the Agent
    String IP;

    public PM() {
        super();
        for(int i=0;i<10;i++){
            vm[i]=new VM();}
        }
    }

VM是另一个具有自己属性的类。

public class VM implements Serializable{
       String osType;
}

通过套接字交换对象pm在两台PC之间进行。 在服务器执行网络发现(因此类名称)之后,服务器端从客户端接收对象。

public class NetworkDiscovery extends TimerTask {
    InetAddress controllerIP;
    int controllerPort;
    static PM pm = new PM();

    NetworkDiscovery() throws UnknownHostException {
        controllerIP=InetAddress.getLocalHost();
        controllerPort=4455;
    }
    public void run() {
        try {
            byte[] recvBuf = new byte[5000];
            DatagramPacket packet = new DatagramPacket(recvBuf, recvBuf.length);
            DatagramSocket dSock = new DatagramSocket(4445);
            dSock.receive(packet);
            int byteCount = packet.getLength();
            ByteArrayInputStream byteStream = new ByteArrayInputStream(recvBuf);
            ObjectInputStream is = new ObjectInputStream(new BufferedInputStream(byteStream));
            pm=(PM)is.readObject();
            System.out.println("object1" +pm.IP);
            is.close();
            dSock.close();
            System.out.println("object" + pm.vm[0].vmName);
        } //exceptions are caught etc.
    }
}

并在客户端将pm对象发送到服务器:

public class ackDiscovery extends TimerTask{
    int agentListenPort;
    InetAddress agentIP;
    ackDiscovery(Connect c) {
        agentListenPort=4445;
        c1=c;
    }
    public void run() {
        ObjectOutputStream os = null;
        try {
            PM pm = new PM();
            {
                pm.IP = InetAddress.getLocalHost().toString();
                pm.vm[i].osType = d1.getOSType();
                System.out.println("VMname" +i +pm.vm[i].osType);
                pm.vm[i].status = d1.isActive();
            }
            InetAddress address = InetAddress.getByName("Server_IP");
            ByteArrayOutputStream byteStream = new ByteArrayOutputStream(15000);
            os = new ObjectOutputStream(new BufferedOutputStream(byteStream));
            os.flush();
            os.writeObject((PM) pm);
            os.flush();
            byte[] sendBuf = byteStream.toByteArray();
            DatagramPacket packet = new DatagramPacket(sendBuf, sendBuf.length, address, 4445);
            int byteCount = packet.getLength();
            DatagramSocket dSock = new DatagramSocket();
            System.out.println("Quote of the Moment: " + pm.vm[0].osType);
            dSock.send(packet);
            os.close();
            dSock.close();
        } //exceptions caught etc.
    }
}

所有的vm和pm细节都在客户端填充(我通过打印它来检查它)。 在服务器端,转移后只有pm详细信息填充在本地pm对象上。 在服务器端显示虚拟机详细信息会给我空值。

我的疑问:

  1. 不传输具有子对象的对象也意味着整个父+子对象被传输?
  2. 我是否必须分别手动传输vm和pm对象?

编辑-

public class VM implements Serializable{
       String osType,vmName; //on server's side, these are still null
       int UUID,osVersion;   // on the server's side, these are 0. Are integer variables initialised to a default of zero?
       }

正如@Hovercraft ...提到的那样,如果字段没有标记为transient ,则VM应该被序列化。 transientdefinition )是Java关键字,表示序列化应该忽略该字段。 如果vm字段被标记为transient则它在接收器上始终为null 在你的情况下, vm不应使用临时关键字。

不确定问题出在哪里,但我认为我会对此发表评论。

  • 您可能在不同的PC上使用不同版本的软件吗? 接收器是否在PM具有vm字段?
  • 每次更改类以确保PM类在客户端和服务器上匹配时,最好增加您的Serializable ID。 您还可以删除serialVersionUID并让VM生成一个确保您在两侧都有匹配的类。 如果它们不匹配,这将给出例外。
  • 您可能知道这一点,但要小心,因为您使用DatagramPacketPM大小不会超过数据包大小。 它们可以碎片化,重新排序,根本不交付等。我怀疑ObjectInputStream是否会为您提供部分对象。
  • 确保捕获异常并正确记录关联的消息,尽管在抛出时不会得到任何对象。

仅供后人使用,建议生成serialVersionUID而不是依赖VM的运行时计算。 更改对象时是否更改ID取决于要实现的分布式系统类型。

顺便说一下, serialVersionUID是一个每类标识符,可帮助Java VM验证序列化的类是否与要反序列化的类的定义相匹配。 反序列化对象时,VM查找该对象的类并确保UID相同。 如果不是,则在反序列化对象时会引发InvalidClassException异常。 如果2个不同的类具有相同的UID则无关紧要。

希望这可以帮助。

数组是Java中的第一类对象,它们不是可序列化的对象。 这个问题有三种基本解决方案:

字段可以声明为瞬态。 可以实现writeObject()/ readObject()方法。 可以声明serialPersistentFields。

希望这会有所帮助。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM