How to: Send collection of objects over a socket? - java

Suppose I want to send a collection of objects over a network via a socket in Java. For concreteness, suppose I want to send an array of BigInteger objects. The sender should simply send this array in one chunk over the socket, so that the receiver could cast the received object to the proper form.
How can this be accomplished ?
I've tried using ObjectOutputStream to send this array of objects. However, it doesn't go as planned.
Some of the code:
BigInteger[] bigIntegers = new BigInteger[10];
bigIntegers[0] = new BigInteger("0");
bigIntegers[1] = new BigInteger("1");
outputStream = new ObjectOutputStream(socket.getOutputStream());
outputStream.writeObject(bigIntegers);
I assume that the underlying architecture is the same at both ends.
Can someone show how to send such a collection of objects, as well as receive this collection on the other side of the socket?
Thanks,

you can send objects to server socket using
objectOut.writeObject(bigIntegers);
objectOut.flush();
and can retrieve that object at server side using
here client is clientsocket
ObjectInputStream objectIn = new ObjectInputStream(client.getInputStream());
BigInteger[] array = (BigInteger[]) objectIn.readObject();

Related

Passing TreeMap object over Socket (from server to client)

Is it possible to send a TreeMap (containing keys and values) over a socket from server to client?
Writing to a socket is no different than writing to a file. The ObjectOutputStream class abstracts that layer for us. So you can test that your Serialization is working smoothly with file IO; then it is very easy to write to a Socket.
First Step: Test Your Serialization
TreeMap<YourKeyClass, YourValueClass> treeMap =
new TreeMap<>();
buildMyTree(treeMap);
FileOutputStream fout = new FileOutputStream("path/to/your/file.ser");
ObjectOutputStream oos = new ObjectOutputStream(fout);
oos.writeObject(treeMap);
Second Step: Test Your Deserialization
Read your object back to check deserialization:
FileInputStream fin = new FileInputStream("path/to/your/file.ser");
ObjectInputStream ois = new ObjectInputStream(fin);
TreeMap<YourKeyClass, YourValueClass> treeMapFromFile = ois.readObject();
TreeMap is Serializable. Everything runs perfectly fine, as long as YourValueClass does not have complex structure that hinders serialization. For instance you may have recursive references to other objects in your YourValueClass, in which case you have to work on your work on your own writeObject and readObject implementations for Serialization.
So a read and write check is very important to be sure everything runs according to your structure.
Third Step: Move to Socket Programming
Once you are sure your serialization is working, move to socket programming. It is very important that you're confident that your serialization is working perfectly, before moving on to the socket, since if you miss a point on serialization then if anything fails during socket implementation, it will be very hard to find where the problem is.
Server Side:
//initialize your socket
//start listening on your socket
TreeMap<YourKeyClass, YourValueClass> treeMap = new TreeMap<>();
buildMyTree(treeMap);
ObjectOutputStream oos = new ObjectOutputStream(socketToClient.getOutputStream());
oos.writeObject(treeMap);
Client Side:
//initialize your socket
ObjectInputStream ios = new ObjectInputStream(socketToServer.getInputStream());
TreeMap<YourKeyClass, YourValueClass> treeMapFromSocket = ois.readObject();
You can use refer to the following sources:
Serialization
Oracle Tutorial for Java Socket Prog
ServerSocketChannel
Yes, it's possible.
java.util.TreeMap implements interface java.io.Serializable.
Also all of keys and values int TreeMap must implements this interface.

Sending serialized objects and byte[] from same stream

I have a client server application, they communicate throught objectoutputstream and objectinputstream. I send serialized objects from one to other, but now i want to send files also. If i pass the byte[] of file inside a serialized object it can be transmitted but the object stays at objectoutputstream and objectinputstream and after some sends if the file is big enough i get memory exception. If i send it like:
File file = new File("C:\\a.txt");
FileInputStream fis = new FileInputStream(file);
BufferedInputStream bis = new BufferedInputStream(fis);
byte[] buffer = new byte[1024*1024*10];
int n = -1;
while((n = bis.read(buffer))!=-1) {
oos.write(buffer,0,n);
}
and read it:
while ((fromServer = ois.read()) != null) {
}
works well.
My question is, do i have to implement a system to know if i have to writeObject/readObject or just write/read? Do i have to get rid of serialized communication, do i have to create another streams for read and write?
You have to define a protocol which doesn't have any ambiguity, and stick to this protocol on the client and server.
For example, if you send a stream of bytes, and then an object, you have no way, at the receiving side, to know when the stream of bytes ends, and when the object begins.
A protocol to sole this problem might be:
send an int (4 bytes) which is the size N of the file
send N bytes
send an object
The receiving side can then read the size (N), then read N bytes from the stream, then read the object.

Sending variables using sockets

I've started work on a simple newtworking project which creates a new thread for each connection and I'm trying to send multiple things across. What I'm wondering is there an easy way of simple say declaring a variable sending that whole variable to the server and that being sent to other clients. For example if I wanted to send a simple integer array? Basically how would I send an array or even an image across a socket?
Yes, it is possible. What you are looking for is called serialization and can be used to send entire objects through a stream (socket, file, etc.). Have a look at this java socket serialization tutorial.
Check the docs on ObjectOutpuStream and ObjectInputStream.
Basically what you have to do is have any custom type that you want to be serialized implement the Serializable interface:
class MyCustomType implements Serializable {
...
}
This is a marker interface that tells the runtime that this type can be sent over a stream.
Next, once your connections are set up you can obtain the socket input/output stream and write objects using ObjectOutputStream:
MyCustomType obj = new MyCustomType();
ObjectOutputStream oos = new ObjectOutputStream(client.getOutputStream());
oos.writeObject(obj);
oos.flush();
or read them using ObjectInputStream:
ObjectInputStream ois = new ObjectInputStream(client.getOutputStream());
MyCustomType obj = (MyCustomType) ois.readObject();
(client above is a Socket).

Sending List through DatagramSocket?

I have a spreadsheet application in Java, and one of the features it provides (which I developed) is sheet sharing. Basically, anyone can be a client or a server because the app has both server and client code. The user who is the server creates the share, specifies the IP, and then the share is created and active (best case scenario) with the server listening for clients on its IP and selected port.
For auto-discovery, I am using DatagramSockets via UDP broadcasts, while the 'real communication' is TCP-based (after the client is already connected). However, I'm trying to send a List through that UDP socket and I don't know how to do it. That List contains the active shares on the server that I need to send to the client so it knows what it can connect to.
It goes like this:
Client -> looks for active servers by sending a packet to the network -> server listens and sends a packet back. This packet should be the List (if it is possible to send it via these kind of sockets).
Can anyone shed some light on my question? Thank you.
You can convert your List to a byte[] before sending, and convert it back to a List on the reciever using Java Serialization.
// Sender
List list = new ArrayList();
ByteArrayOutputStream out = new ByteArrayOutputStream();
ObjectOutputStream outputStream = new ObjectOutputStream(out);
outputStream.writeObject(list);
outputStream.close();
byte[] listData = out.toByteArray();
// Reciever
ObjectInputStream inputStream = new ObjectInputStream(new ByteArrayInputStream(listData));
list = inputStream.readObject();
Just make sure all the objects you put in your List implements Serializable.

Client / server communication using serialized objects

I try to establish a client / server connection for a mastermind game.
I though of using enumerations to represent the different pegs and made them serializable.
Then I have to implement the connection, using serversocket and getting the socket using accept and so on.
Once the connection is established, I first have to read for client objects, and it is where I am having problems...
Here is a piece of my code, which produces EOFException before I could ever do anything!
(the client data is send on user's interaction).
ObjectInputStream ois =
new ObjectInputStream(socket.getInputStream());
ArrayList<Peg> combination = new ArrayList<Peg>();
do
{
combination.clear();
for (int i = 0; i < 4; i++)
{
combination.add((Peg)ois.readObject());
}
}
while (!checkCombination(combination));
ois.close();
socket.close();
Thank's in advance
We need more details. How are you syncing up writes from the client and the reads on the server? Can you post more details?
BTW, is using raw sockets an absolute requirement? If not, try out RMI which does what you want to do with much less hassle (i.e. sending across Java objects transparently and much more).
If you are getting an EOFException it means the other end has closed the connection.
If you want to send a list, just send the list. i.e.
// on the sender
List<Peg> list =
oos.writeObject(list);
// on the receiver
List<Peg> list = (List<Peg>) oid.readObject();

Categories