views:

79

answers:

4

Let's assume I want to send many messages between 2 programs made in java that use TCP sockets.

I think the most convienient way is to send objects like:

PrintStream ps = new PrintStream(s.getOutputStream());

ObjectOutputStream oos = new ObjectOutputStream(ps);

  some_kind_of_object_here;

  oos.writeObject(some_kind_of_object_here);

 ps.print(oos);

I want to send, strings, numbers, HashMaps, boolean values How can I do this using fx 1 object that can store all that properties? I though about ArrayList that is serializable and we can put there everything but is not elegant way. I want to send different types of data because user can choose from a variety of options that server can do for it. Any advices?

+2  A: 

Have you considered using RMI?

Otherwise stick with Serializable or even Externalizable, if you need extra performance.

You don't need wrapper classes like Lists. Of course you can build your own wrapper object thats holds togeher all associated data. Such "application data units" will help you to take care of the right order you send the entites. As long as all member are Serializable, the complete object graph will be serialized automagically, once you put the wrapper object into the object stream.

If you don't use wrapper classes, just be sure every object/type you want to transer implements at least Serializable. Then you have to verify that the order of data send corresponds with the order you except data to arrive.

PartlyCloudy
yep, I want to use this 1 big object to store all informations but i don't know how to read it on another side,I can make class that has the same fields but UUID (or sth like that) will not match
rmaster
Java does all that stuff for you, like here: http://www.java2s.com/Code/Java/Network-Protocol/ServeentireobjectsusingObjectOutputStream.htm Instead of using a hash table like in the example, use your arbitrary class, which must exist in the classpath on both nodes.
PartlyCloudy
Or did I misread it? Is your problem that you're creating COPIES of the object? Then use RMI and export your object.
PartlyCloudy
A: 

If you need to keep packets small you can use a plain Object[], place whatever you want inside and use an enum that specifies the packet type, allowing you to how many and which kinds of objects are store inside the message.

class Message
{
  Type t;
  Object[] params;
}

of course you will have to switch according to Type t when choosing what to do with every packet, but since protocols are usually FSMs (it depends on what you are coding) this would work well without wasting too much space or allocating lists when it's not needed.

Jack
If you want to do it like that, use Serializable[] instead. However I don't see the point here. Just use a regular class and add our values as members. Using this array/list just adds an overhead when you have to cast back the types to your original types when unmarshalling.
PartlyCloudy
Yes, Serializable is ok (but it's just a constraint, it doesn't really mean anything)! In any case you could do like PartlyCloudy suggests, if you don't have many kinds of different packets with different params/types of params.
Jack
Of course there is a difference. If you put a not-serializable object into the array, it will fail during compile time. In your version, it will fail during marshalling – which is bad.
PartlyCloudy
That's not true, I'm using this approach inside a Serializable class that contains the array. During marshalling no exceptions are throwns neither it fails.. that's why I say it's just a constraint..
Jack
Because your are only putting in objects into the array that are Serializable. If you try to put in something, that is not Serializable, the program will still compile. However it will crash during rumtime.
PartlyCloudy
Yes, that's why it is just a compile-time constraint.. they just have to be serializable at run-time..
Jack
A: 

The way you wrote you code, you already can send any Java object. Those objects, of course, ihclude "strings, numbers, HashMaps, boolean values".

Just write into ByteArrayOutputStream:

ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.write(javaObject);
oos.close();
socket.write(baos.toByteArray())
Vladimir Dyuzhev
There is no need for ByteArrayOutputStream, ObjectOutputStream handles all that stuff automatically.
PartlyCloudy
I know how to send that kind of object but i want to send all this strings, numbers, HashMaps, boolean values in 1 object, using just:oos.write(This_1_big_powerfull_object);
rmaster
+1  A: 

Master, you know you can send any serializable object across a socket to another JVM, yes?

If so, the easiest way is to have a serializable object containing all your objects and then just forward that. A list of objects is probably the most simple. You can then deserialize it on the other side, and process the objects in the list in whatever way you need.

I would suggest you read up on the serialization technology in Java, so you know all the smart things you can do.

http://java.sun.com/javase/7/docs/technotes/guides/serialization/index.html

Thorbjørn Ravn Andersen
it's good link, i've already found there sth interesting, tak
rmaster