javaudpdatagram

UDP datagram is sent but never received


I made two different java classes, for a client and for a server, with send and receive methods in each. According to the task, I had to make server-to-client connection via DatagramPacket and client-to-server via DatagramChannel. The last one works great, but I have trouble with datagrams -- they are sent from the server and never received on the client. What's wrong?

public class TransferClient implements Serializable{
    private static final long serialVersionUID = 26L;
    public TransferClient() {

    }

    public void send(Command com) throws IOException {
        SocketAddress socketAddressChannel = new InetSocketAddress("localhost", 1);
        DatagramChannel datagramChannel=DatagramChannel.open();
        ByteBuffer bb;
        datagramChannel.connect(socketAddressChannel);
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(baos);
        oos.writeObject(com);
        oos.flush();
        bb=ByteBuffer.wrap(baos.toByteArray(),0, baos.size());
        datagramChannel.send(bb,socketAddressChannel);
        baos.close();
        oos.close();
    }

    public Command receive() throws IOException, ClassNotFoundException {
        SocketAddress address = new InetSocketAddress(2029);
        DatagramSocket s = new DatagramSocket();
        DatagramPacket inputPacket = new DatagramPacket(new byte[1024],1024, address);
        s.receive(inputPacket);
        ByteArrayInputStream bais = new ByteArrayInputStream(inputPacket.getData());
        ObjectInputStream ois = new ObjectInputStream(bais);
        return (Command) ois.readObject();
    }
}

public class TransferServer {
    public TransferServer(){

    }

    public void send(Command com) throws IOException {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(baos);
        byte[] buffer;
        oos.writeObject(com);
        oos.flush();
        buffer=baos.toByteArray();
        SocketAddress address = new InetSocketAddress("localhost",2029);
        DatagramSocket s = new DatagramSocket();
        DatagramPacket outputPacket = new DatagramPacket(buffer,buffer.length,address);
        s.send(outputPacket);
    }


    public Command receive() throws IOException, ClassNotFoundException {
            SocketAddress socketAddressChannel = new InetSocketAddress("localhost", 1);
            DatagramChannel datagramChannel = DatagramChannel.open();
            datagramChannel.bind(socketAddressChannel);
            ByteBuffer bb = ByteBuffer.allocate(1024);
            datagramChannel.receive(bb);
            ByteArrayInputStream bais = new ByteArrayInputStream(bb.array());
            ObjectInputStream ois = new ObjectInputStream(bais);
            Command command;
            System.out.println(ois.available());
            command =(Command) ois.readObject();
            datagramChannel.close();
            ois.close();
            bais.close();
            return command;
    }
}

Solution

  • You have to specify the port on which to bind your DatagramSocket in order to receive your data. Otherwise it will bind to the first available port found on your machine.

    And you don't need the SocketAddress here, but you do need to take account of the actual received packet length.

    See java.net.DatagramSocket Documentation

    In the receive() method of your TransferClient class:

    public Command receive() throws IOException, ClassNotFoundException {
    
        DatagramSocket s = new DatagramSocket(2029); //Add your port Here
    
        DatagramPacket inputPacket = new DatagramPacket(new byte[1024],1024);
        s.receive(inputPacket);
        ByteArrayInputStream bais = new ByteArrayInputStream(inputPacket.getData(), 0, packet.getLength());
        ObjectInputStream ois = new ObjectInputStream(bais);
        return (Command) ois.readObject();
    }