views:

53

answers:

4

Hi to all of you;

I am trying to send a serialized object from a server process to a client process in Java using UDP. The problem is that the client is being blocked on the receive method. Can someone help?!

here is the server code for sending the object:

  ClientModel C1= new ClientModel(100,"Noor","Noor",38,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);

and here is the client code for receiving the 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 object to be able to reconstruct but I cannot receive the packet itself. I'm stuck on this for all most 5 hours!!

In case you have an idea how to implement this, just post a comment.

Thanks

+1  A: 

I dont know what you want to accomplish in the end, but working with UDP is not so easy... the main reason is in the Description of the DatagramPacket Object:

Datagram packets are used to implement a connectionless packet delivery service. Each message is routed from one machine to another based solely on information contained within that packet. Multiple packets sent from one machine to another might be routed differently, and might arrive in any order. Packet delivery is not guaranteed.

A good tutorial when working with udp is http://download.oracle.com/javase/tutorial/networking/datagrams/clientServer.html

About your blocking:

Receives a datagram packet from this socket. When this method returns, the DatagramPacket's buffer is filled with the data received. The datagram packet also contains the sender's IP address, and the port number on the sender's machine.

This method blocks until a datagram is received. The length field of the datagram packet object contains the length of the received message. If the message is longer than the packet's length, the message is truncated.

I didnt really test it, but I am pretty sure - based on the description - that the datagramsocket.reseive function will block until the packet is filled (in your case until 100000 bytes are received).

I would suggest you start with a datagrampacket with a fixed known length, where you transmit the size of the actual payload. Something 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, client, 1234);
      socket.send(packet);

      // now send the payload
      packet = new DatagramPacket(Buf, Buf.length, client, 1234);
      socket.send(packet);

      System.out.println("DONE SENDING");
    } catch(Exception e) {
        e.printStackTrace();
    }
}

On the other side you now KNOW your sizes:

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();
    }
}

The CientModel clas sI used:

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 just fine. Hope that helps (I got the byte-To-int and around from http://www.tutorials.de/java/228129-konvertierung-von-integer-byte-array.html)

Niko
I'm not tested either, but from description of C recvfrom(2), it's evident that reading from UDP connection can return as soon as whole datagram is read and actual number of read bytes is returned (in case of JDK it will be in DatagramPacket.length field). I suggest writing simple Java echo client/server to test behavior.
Victor Sorokin
A: 

Thanks Niko for your answer.

I just wanted to know how to flatten an object at the server, send it through UDP at the server. Then at the client side, get the packet and reconstruct the object.

So, i u can help me on this. According to me, the way i am implementing it is ok but i dont know it is blocking at the client on socket.receive()

Noor
I updated my code - the one I posted actually compiles and works just fine
Niko
A: 

Hi Niko,

I have copied the code you have updated exactly the same but unfortunately it still block on the receive if I am sending a custom object

Noor
the code worked fine for me... you have to start the second main first (it will block and wait for data), once you run the first main (which transmits the data) the server will receive the object, unblock and run the data. Make sure to disable any antivirus/firewall that might block the traffic!
Niko
A: 

Sorry Niko, the answer you is ok?? thanks this has greatly helped me!!

Noor