Search code examples
javasocketsdatagram

Socket Programming java using datagram multiple packets


I am trying to make a client-server program. Where in client i am getting multiple inputs from user and i have to pass it to server. Server uses that info and does some calculation and sends back the result. important parts from Client code:

private byte[] buf = new byte[256];
private byte[] buf2 = new byte[256];
private byte[] buf3 = new byte[256];
while (true) {

Arrays.fill(buf, (byte) 0); 

buf = jTextField1.getText().trim().getBytes();
sendPacket = new DatagramPacket(buf, buf.length, address, 8000);
socket.send(sendPacket);

buf2 = jTextField2.getText().trim().getBytes();
sendPacket = new DatagramPacket(buf2, buf2.length, address, 8000);
socket.send(sendPacket);

buf3 = jTextField3.getText().trim().getBytes();
sendPacket = new DatagramPacket(buf3, buf3.length, address, 8000);
socket.send(sendPacket);

//Get result from Server
socket.receive(recivePacket);
double result  = Double.parseDouble(new String(buf).trim());
System.out.println("Result" +result);

}

On Server side I am trying to recieve the data(which is not working)

   byte[] buf = new byte[256];
   DatagramPacket  recivePacket = new DatagramPacket(buf, buf.length);
   DatagramPacket dgp = new DatagramPacket(buf, buf.length);
    while (true) {
            Arrays.fill(buf, (byte) 0);
            serverSocket.receive(recivePacket);

            System.out.println("host Name is " + 
   recivePacket.getAddress().getHostName() + '\n');

            while (true) {
                serverSocket.receive(dgp);
                System.out.println("String=====" + new String(buf));
            }

Please help me out here. What is wrong with this code ... I am completely stuck So, its strange that sometimes it works. But it gives me value from last buffer. Other values are lost. Thanks in advance


Solution

  • So I think each time you recieve something on the server, you need to create a new DatagramPacket/byte[] for that. What I do is creating e a new DatagramPacket each time I recieve something like this:

    DatagramPacket packet = new DatagramPacket(new byte[max_data_size], max_data_size);
    socket.receive(packet);
    

    My max_data_size is normally around 1024 bits.

    Then you could read stuff like client, port, length etc:

    InetAddress address = packet.getAddress();
    int port = packet.getPort();
    int len = packet.getLength();
    byte[] data = packet.getData();
    

    And usually, you should then be able to simply send a new datagramPacket back to the given InetAddress/port.

    You want multiple inputs from the user? Pack everything in only one package.


    private YourClass newInstance(byte[] bytes){
        ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
        ObjectInput in = null;
        YourClass o = null;
        try {
            in = new ObjectInputStream(bis);
            o = (YourClass)in.readObject();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (ClassCastException e){
            e.printStackTrace();
        }finally {
            try {
                if (in != null) {
                    in.close();
                }
            } catch (IOException ex) {
                // ignore close exception
            }
        }
        return o;
    }
    
    private byte[] toBytes(YourClass object){
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ObjectOutput out = null;
        byte[] bytes = new byte[1];
        try {
            out = new ObjectOutputStream(bos);
    
            object.setTimestamp(System.currentTimeMillis());
    
            out.writeObject(object);
            out.flush();
            bytes = bos.toByteArray();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                bos.close();
            } catch (IOException ex) {
                // ignore close exception
            }
        }
        return bytes;
    }