updated object not properly sent over socket

D

Digital Puer

Hi, I am encountering a strange problem with a client/server socket
program. In a tight loop, I am changing a field of an object and then
sending it over a socket. However, the change is not evident at the
receiving socket at the other end! This problem occurs with the
client/server pair on the same machine.

My code looks like this:


public class Datum implements java.io.Serializable
{
public String _data;
Datum() { }
}


In the sending program, I have this code:
Datum data = new Datum();
for (int i = 0; i < 10; i++)
{
data._data = "data"+i;
System.out.println("sending " + data._data);
oos.writeObject(data);
oos.flush();
}

At the sender, this properly prints data1, data2, data3, etc.
However, at the other end of the socket, I am getting data1, data1,
data1, etc.
When I instantiate 'new Datum' inside the loop, it works properly.

Does anyone have an idea?

Below is all the source code.


public class Datum implements java.io.Serializable
{
public String _data;
Datum() { }
}


import java.io.*;
import java.net.*;

class Client
{
public static void main(String argv[])
{
try
{
Socket socket = new Socket("localhost", 3000);
ObjectInputStream ois = new
ObjectInputStream(socket.getInputStream());

Datum data;
for (int i = 0; i < 10; i++)
{
data = (Datum) ois.readObject();
System.out.println("got '"+data._data+"'");
}
}
catch(Exception ex)
{
//System.out.println(ex);
ex.printStackTrace();
}
}
}



import java.io.*;
import java.net.*;

public class Server
{
public static void main(String argv[])
{
//send_method_1(); // THIS ONE WORKS
send_method_2(); // THIS ONE DOESN'T WORK!!
}


/*********************************************************************/
static void send_method_1()
{
try
{
ServerSocket socket = new ServerSocket(3000);
System.out.println("waiting for connection");
Socket client_socket = socket.accept();

ObjectOutputStream oos =
new
ObjectOutputStream(client_socket.getOutputStream());

for (int i = 0; i < 10; i++)
{
Datum data = new Datum();
data._data = "data"+i;
System.out.println("sending " + data._data);
oos.writeObject(data);
oos.flush();
}
}
catch(Exception ex)
{
//System.out.println(ex);
ex.printStackTrace();
}
}





/*********************************************************************/
static void send_method_2()
{
try
{
ServerSocket socket = new ServerSocket(3000);
System.out.println("waiting for connection");
Socket client_socket = socket.accept();

ObjectOutputStream oos =
new
ObjectOutputStream(client_socket.getOutputStream());

Datum data = new Datum();
for (int i = 0; i < 10; i++)
{
data._data = "data"+i;
System.out.println("sending " + data._data);
oos.writeObject(data);
oos.flush();
}
}
catch(Exception ex)
{
//System.out.println(ex);
ex.printStackTrace();
}
}
}
 
H

hiwa

You should use writeUnshared() method
instead of simple writeObject().
For the rationale for doing it, read the
Java Serialization Specification.
 
D

Digital Puer

Thanks for the info. writeObject's behaviour is completely unintuitive.
What's the point of resending objects that have already been sent??
 
M

Mike Schilling

Digital Puer said:
Thanks for the info. writeObject's behaviour is completely unintuitive.
What's the point of resending objects that have already been sent??

A series of writeObject()s are intended to write a consistent graph of
objects. When an object is first sent it's assigned an ID: object #1, 2, 3,
etc. If it's sent again, rather than sending the entire object, what's sent
is the information "Here's #12 again". Say the following graph is written:

A->B->C
->C

That is, A points to B and C and B also points to C. A, B, and C are
written once each, together with the information about which points to
which, more or less:

Here's A, it's #1.
Here's B, it's #2.
#1 points to #2.
Here's C, it's #3.
#1 points to #3.
#2 points to #3.

When the result is deserialized, the graph is reconstititued correctly. If,
on the other hand, C had been written each time it was referenced, the
deserialization would create two copies of C, which would be incorrect.

So what you're seeing is that each or your writeObject() calls merely writes
the ID of the object again, rather than reserializing the object. That's
why you don't see the changes.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,053
Latest member
BrodieSola

Latest Threads

Top