Java – send and receive serialized objects over UDP
I tried to send a serialized object from the server process to the client process in Java using UDP The problem is that the method the client is receiving is blocked Can I help you?
Here is the server code of the sending object:
ClientModel C1= new ClientModel(100,"Noor",38,"asd"); ByteArrayOutputStream baos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(baos); oos.writeObject(C1); oos.flush(); byte[] Buf= baos.toByteArray(); packet = new DatagramPacket(Buf,Buf.length,client,port); socket.send(packet);
Here is the client code of the receiving object:
byte[] buffer = new byte[100000];
packet = new DatagramPacket(buffer,buffer.length );
socket.receive(packet);
System.out.println("packet received");
I just want to receive the reconstructed object, but I can't receive the packet itself
Solution
I don't know what you want to accomplish, but using UDP is not so easy... The main reason is that in the description of datagram packet object:
A good tutorial for using UDP is http://download.oracle.com/javase/tutorial/networking/datagrams/clientServer.html
About your blockade:
I didn't really test it, but I'm pretty sure - based on the description - datagram socket The reseive function will block until the packet is filled (in your case, until 100000 bytes are received)
I suggest you start with a data transmitter with a fixed known length, and you can transfer the size of the actual payload It's like:
public static void main(String[] args) {
ClientModel c1 = new ClientModel ();
c1.data = 123;
c1.name = "test";
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(c1);
oos.flush();
// get the byte array of the object
byte[] Buf= baos.toByteArray();
int number = Buf.length;;
byte[] data = new byte[4];
// int -> byte[]
for (int i = 0; i < 4; ++i) {
int shift = i << 3; // i * 8
data[3-i] = (byte)((number & (0xff << shift)) >>> shift);
}
DatagramSocket socket = new DatagramSocket(1233);
InetAddress client = InetAddress.getByName("localhost");
DatagramPacket packet = new DatagramPacket(data,4,1234);
socket.send(packet);
// Now send the payload
packet = new DatagramPacket(Buf,1234);
socket.send(packet);
System.out.println("DONE SENDING");
} catch(Exception e) {
e.printStackTrace();
}
}
On the other side, you now know your size:
public static void main(String[] args) {
try {
DatagramSocket socket = new DatagramSocket(1234);
byte[] data = new byte[4];
DatagramPacket packet = new DatagramPacket(data,data.length );
socket.receive(packet);
int len = 0;
// byte[] -> int
for (int i = 0; i < 4; ++i) {
len |= (data[3-i] & 0xff) << (i << 3);
}
// Now we kNow the length of the payload
byte[] buffer = new byte[len];
packet = new DatagramPacket(buffer,buffer.length );
socket.receive(packet);
ByteArrayInputStream baos = new ByteArrayInputStream(buffer);
ObjectInputStream oos = new ObjectInputStream(baos);
ClientModel c1 = (ClientModel)oos.readObject();
c1.print();
} catch(Exception e) {
e.printStackTrace();
}
}
Cientmodel clas uses:
public class ClientModel implements Serializable{
private static final long serialVersionUID = -4507489610617393544L;
String name = "";
int data = 1;
void print() {
System.out.println(data +": " + name);
}
}
I tested this code and it works well Hope to help (I'm from http://www.tutorials.de/java/228129-konvertierung-von-integer-byte-array.html Start getting bytes to int and around)
Edit: as mentioned in the note, it is usually a very bad idea to mainly use UDP, because you don't know that your packets are received in the correct order, or even all UDP is not guaranteed I haven't done much UDP programming, but the only thing I can rely on (if I understand correctly) is that if you receive a packet, it matches the datagram (65527 bytes - see https://en.wikipedia.org/wiki/User_Datagram_Protocol ), it will contain the whole thing So if you don't care about the order of messages and your objects fit into datagrams, you should be fine
Edit 2: Code: do not use it This is just an example. Ind UDP you should have only one type of packet, and the data has a known size So you don't have to send "size" If you use the code shown above and discard a packet, the next packet will be the wrong size (that is, the first packet is discarded, and suddenly you will check the first byte of the payload for size)
