0

I want to send an object as a UDP packet and then receiving the object on the server. I have the client side figure out, but I can't get the server to read in the datagram correctly.

Client Code:

public void sendMessage() {
        ByteArrayOutputStream bStream = new ByteArrayOutputStream();

        try {
            ObjectOutput oo = new ObjectOutputStream(bStream);
            oo.writeObject(asset);
            // Send it

            byte[] serializedMessage = bStream.toByteArray();

            DatagramPacket sendPacket = new DatagramPacket(serializedMessage,
                    serializedMessage.length, ipAddress, sPort);
            clientSocket.send(sendPacket);
            oo.close();

        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

Server Failed Attempt.

public void startServer() {
    try {
         serverSocket = new DatagramSocket(this.serverPort);
         serverSocket.receive(new DatagramPacket()); /*Code fails here, I realise
         * the constructor does not have input, but I can not figure out how to init
         *a buffer whose size I do not know beforehand.
         */
       this.threadPool.execute(new QueryTask(packet));
    } catch (IOException e) {
       // TODO Auto-generated catch block
       e.printStackTrace();
        }
}

I used the following question Sending Objects Across Network using UDP in Java to send the object in, but it did not show how he received said object.

Question 2: Is it better to create a new thread once i receive and parsed out the packet or should I create a new thread with the DatagramSocket over the Datagrampacket?

Thanks In Advance.

Community
  • 1
  • 1
user597608
  • 387
  • 8
  • 20
  • I know you are specifically asking about Datagram UDP connections, but have you considered RMI/JAX-WS(SOAP)/JAX-REST? – dngfng Oct 18 '12 at 07:06
  • Also you may find that this answers your question: http://stackoverflow.com/questions/3997459/send-and-receive-serialize-object-on-udp-in-java – dngfng Oct 18 '12 at 07:08
  • Go to the source: http://docs.oracle.com/javase/tutorial/networking/datagrams/clientServer.html – Anders R. Bystrup Oct 18 '12 at 07:32

2 Answers2

2

Create a buffer that is one bigger than the largest packet you expect to receive. Then if you ever get a packet that size, it is an overflow. Note that you should re-initialize the DatagramPacket's length before every receive, otherwise it keeps shrinking to the smallest datagram received so far.

If you can process packets quickly enough you don't really need threads at all with UDP, there being no connections to handle.

user207421
  • 305,947
  • 44
  • 307
  • 483
1

As you already seen, datagramm packet needs buffer to write stuff into. I would create buffer which is just big enough for intendet data (UDP specifies 65K for IPV4 and 4G for IPV6). And if I were you , I would not use java.io serialisation as it is going to break on every class change ( or even sometimes compiler change ). Use more robust serialisation means like JSON ( with jackson / gson ) or XML or protobuf

Konstantin Pribluda
  • 12,329
  • 1
  • 30
  • 35
  • 1
    UDP does not 'specify 65K for UDP'. The maximum size of an IPv4 UDP payload is 65535-20-8=65507 bytes. Java Object Serialization does not 'break on every class change' unless you mismanage it – user207421 Oct 18 '12 at 09:33
  • sometimes it breaks on the compiler change and perfromance is not really impressive. – Konstantin Pribluda Oct 18 '12 at 11:54
  • 'Sometimes' is not the same as 'every class change', is it? – user207421 Oct 18 '12 at 11:55
  • Yeah my server is breaking the object when it reconstructs it. It seems that it can't get the variables that are in an abstract base class, but all the variable in the concrete class show up :( – user597608 Oct 18 '12 at 18:50
  • 1
    abstract base class hast to be also serializable down to last turtle, both sides shall be compiled with same compiler etc - grab you gson, or jackson, or protobuf and marshal your data some portable format. – Konstantin Pribluda Oct 18 '12 at 19:45
  • Konstantin- That worked for me. Guess i misunderstood inheritance in java; I thought that extending a class and making the parent class serializable would take care of it for me, but guess not. Live and learn. Oh also for the record, the data type that i receive on my server is not controlled by me, so it has to be a specific java object and not anything else like a JSON, UML...etc. – user597608 Oct 18 '12 at 20:23
  • Serialisation walks up inheritance tree and stops on first class not implementing Serializable. If you are trying to deserialize object serialized by other side, you will have to have same class on your server classpath, and ensure that you recompile / redeploy your server each time. – Konstantin Pribluda Oct 19 '12 at 08:09
  • @KonstantinPribluda Not all the base classes need to be serializable. `java.lang.Object` isn't, for a start. You don't need to use the same compiler at both ends. It is quite possible to have different versions of the class at each end. See the Object Vserioning chapter of the Java Object Serialization Specification. You're spreading a lot of misinformation here. – user207421 Jan 31 '18 at 05:00