【发布时间】:2019-07-09 00:27:43
【问题描述】:
这是我编写的用于通过套接字传输包含任何对象 vm(属于 VM 类)的对象 pm(属于 PM 类)的代码。
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 发生在 2 台 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 对象上。在服务器端显示 vm 详细信息会给我空值。
我的疑问:
- 不传输一个也有子对象的对象,是否意味着整个父子对象都被传输了?
- 我必须分别手动传输 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?
}
【问题讨论】:
-
被序列化对象持有的对象也应该被序列化,只要它们实现了 Serializable 接口(如果没有,这应该抛出异常)并且它们没有被标记为瞬态。您确定 VM 变量在您序列化 PM 对象时实际上引用了一个有效的引用吗?
-
嗯,您似乎确实检查了我的最后一个问题。
-
@HovercraftFullOfEels- 是的,我让 VM 类也实现了 Serializable 。 VM 是有效的,因为一旦我填充了 vm 对象,我就会显示内容。
-
是的,在我的第一条评论被锁定后,我看到了。看起来您将不得不进一步调试它,也许通过简化代码以尝试隔离问题。
-
你觉得我怎么能做到?我已经测试了填充并检查客户端是否正在发送它。另外,我检查了服务器确实收到了最新的副本。我还向 vm 添加了其他属性。我在服务器端单独显示了所有 vm 属性。虽然字符串值仍为 NUll,但 int 值为 0(在客户端为 8)。怎么样?
标签: java sockets serialization