I am writing a client-server program using socket programming in Java. I need to send multiple values to the server. Can I store this value in a structure object and send the structure object to the server?
You can do this using ObjectOutputStream and ObjectInputStream. You can send any Object that implements the Serializable interface (also note that any Objects within the Object has to implement it as well). To for instance send an array of SomeObject and then SomeOtherObject:
For instance, to send an array of SomeObject and SomeOtherObject:
ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
oos.writeObject(new SomeObject[]{new SomeObject(), new SomeObject()});
oos.writeObject(new SomeOtherObject());
To read them:
ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
SomeObject[] obj = (SomeObject[]) ois.readObject();
SomeOtherObject someOtherObj = (SomeOtherObject) ois.readObject();
Note:
Related
I'm trying to send an object over the network to another computer (or the same computer) and then have said computer send an object back.
On the sending computer, I send the object and receive the returned object:
ObjectOutputStream objectOutputStream = new ObjectOutputStream(socket.getOutputStream());
objectOutputStream.writeObject(object);
Object returnedObject;
socket.setSoTimeout(timeout);
try (ObjectInputStream ois = new ObjectInputStream(socket.getInputStream())) {
returnedObject = (Object) ois.readObject();
}
return returnedObject;
On the receiving computer, I receive the object:
Object object;
socket.setSoTimeout(timeout);
try (ObjectInputStream ois = new ObjectInputStream(socket.getInputStream())) {
object = (Object) ois.readObject();
}
return object;
and then send an object back:
socket.setSoTimeout(timeout);
ObjectOutputStream objectOutputStream = new ObjectOutputStream(socket.getOutputStream());
objectOutputStream.writeObject(object);
The error I get back is:
SEVERE: null java.net.SocketException: Socket is closed at
java.net.Socket.setSoTimeout(Socket.java:1137) at
and it occurs while attempting to send an object back on the receiving computer.
The socket on the sending computer is using the same address and port as the socket on the receiving computer.
This exception means that you closed the socket and then continued to use it. Specifically, you closed the ObjectInputStream at the end of the try-with-resources block where it is declared. That closes the other stream of the socket and the socket itself.
Don't use new object streams per transfer. Use the same ones for the life of the socket, at both ends.
You are using a very small-scoped try-with-resources:
try (ObjectInputStream ois = new ObjectInputStream(socket.getInputStream())) {
returnedObject = (Object) ois.readObject();
}
This code is interpreted as:
Get the input stream and build an ObjectInputStream around it.
Read an object from the object stream
Close the ObjectInputStream.
When you close the ObjectInputStream it automatically closes the InputStream that backs it, which is the socket's input stream. And the documentation of getInputStream says:
Closing the returned InputStream will close the associated socket.
You should make sure the try-with-resources has a bigger scope that covers the entire lifetime of the socket, or avoid using try-with-resources and make sure you close the ObjecInputStream properly when you are done with it or when there is an error.
I'm currently working on a small chat program, and for my next step I would like to send a hashtable to my clients, from my server.
However, so far I was using
PrintWriter out = new PrintWriter(socket.getOutputStream());
in my Server class, and
Scanner in = new Scanner(socket.getInputStream());
in my Client class, which were used to transport messages in form of strings from both sockets to the respective other end of the connection.
This does not work for Hashtables anymore, considering they are no primitive datatype.
What would I have to use instead to be able to send my Hashtable fully working to my client?
Since Hashtable implements the java.io.Serializable interface, you can serialize the object and send it over the socket's output stream:
Hashtable table = new Hashtable(); // TODO: avoid raw types
...
ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
oos.writeObject(table);
oos.close();
To read the object in the client, you need to use an ObjectInputStream:
InputStream is = socket.getInputStream();
ObjectInputStream ois = new ObjectInputStream(is);
Hashtable table = (Hashtable) ois.readObject();
I am working on some Android Project & trying to pass object over Datagram Socket to some another device
Object contains 'String' Data Members of the class ( UserName,Services) ..
How can I do that??
Layer an ObjectOutputStream on top of a ByteArrayOutputStream on the sending side. Gather the bytes from the ByteArrayOutputStream (after the write), and send that in your datagram packet. Do the reverse on the receiving side to unpack the data back into an Object.
Pseudocode for your sending side:
final ByteArrayOutputStream baos = new ByteArrayOutputStream(6400);
final ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(o);
final byte[] data = baos.toByteArray();
final DatagramPacket packet = new DatagramPacket(data, data.length);
// Send the packet
Object transport via datagram packets
you can not send object via nework as object , you have to convert it to array of bytes by using this classes
ObjectOutputStream
ByteArrayOutputStream
and then send it via DatagramPacket class, but your own class should be serializable by adding implementing serializable interface if you look to the link above you will get more details step by step and more helpful
I have a server and a client. The server receives two command strings: add or remove. If server receives add, it adds the object it receives from the socket to a local list. Is it acceptable to open two different streams consecutively to receive two different objects?
Example:
/* To read the command */
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
/* To read the object */
ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
No, that is not necessary. String is Serializable. You could do something like this:
String s = (String) ois.readObject();
Object o = ois.readObject();
if("add".equals(s)){
list.add(o);
} else if ("remove".equals(s)){
list.remove(o);
}
Just make sure you use ObjectOutputStream.writeObject to send both your command and object.
hello i have a basic client-server system running using java sockets.
my problem is, that an object that i send from the client to the server does not contain the correct data after it has been sent once.
the first time i send it, it arrives with the correct values, but when i send it another time with different values, it still arrives at the server with the same values as the first time. it also happens if i send a completely different instance of that class. it always arrives with the data, which have been sent the very first time.
when i try this with other objects like java.lang.String it seems to work.
the problematic class looks like this:
public class Vector3f implements Serializable {
private static final long serialVersionUID = 2838034155614698213L;
public float x, y, z;
}
i use objectinputstream and objectoutputstream on both the server and the client to send and receive objects.
let me know, if you need any more information about the system.
thanks!
My guess is that you're changing the values of the fields and then retransmitting the same object. The ObjectOutputStream will notice that it's already sent the original object, and just send a reference the second time.
You could avoid this by calling reset() on the ObjectOutputStream - but I'd be tempted to just use separate instances anyway, possibly even making the class immutable. (Public mutable fields are almost never a good idea.)
The best way in case of serialization you should convert the object into a byte array object and then write into the socket.
// Serialize to a file
ObjectOutput out = new ObjectOutputStream(new FileOutputStream("filename.ser"));
out.writeObject(object);
out.close();
// Serialize to a byte array
ByteArrayOutputStream bos = new ByteArrayOutputStream() ;
out = new ObjectOutputStream(bos) ;
out.writeObject(object);
out.close();
// Get the bytes of the serialized object
byte[] buf = bos.toByteArray();
// Deserialize from a file
File file = new File("filename.ser");
ObjectInputStream in = new ObjectInputStream(new FileInputStream(file));
// Deserialize the object
Object obj = (Object) in.readObject();
in.close();
// Get some byte array data
byte[] bytes = getBytesFromFile(file);
// see Reading a File into a Byte Array for the implementation of this method
// Deserialize from a byte array
in = new ObjectInputStream(new ByteArrayInputStream(bytes));
in.close();