-1

I've searched for answers, but can't quite fix the code. I want the client to send numbers to the server, the server adds up 2 numbers and sends them back. The thing is, client sends them to the server, server adds them up (at least I think it does) but it doesn't send anything back. I'm posting Client code now:

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        InetSocketAddress ep = new InetSocketAddress("127.0.0.1", 1234);
        String broj1, broj2;
        Scanner sc = new Scanner(System.in);
        System.out.print("Unesite 1. broj: ");
        broj1 = sc.nextLine();
        System.out.println();
        System.out.print("Unesite 2. broj: ");
        broj2 = sc.nextLine();
        if(broj1.contains("[a-zA-Z+]")==true&&broj2.contains("[a-zA-Z+]")){
            System.out.println("Niste unijeli brojeve.");
            System.exit(0);
        }
        byte[] brojJedan = new byte[256];
        byte[] brojDva = new byte[256];
        brojJedan = broj1.getBytes();
        brojDva = broj2.getBytes();
        DatagramPacket packet1 = new DatagramPacket(brojJedan, brojJedan.length, ep);
        DatagramPacket packet2 = new DatagramPacket(brojDva, brojDva.length, ep);
        try(DatagramSocket Klijent = new DatagramSocket(1000)){
            Klijent.send(packet1);
            Klijent.send(packet2);
            byte[] rezultat = new byte[256];
            DatagramPacket packetRezultat = new DatagramPacket(rezultat, rezultat.length, ep);
            Klijent.receive(packetRezultat);
            System.out.println(new String(packetRezultat.getData(), 0, packetRezultat.getLength()));
        }catch(Exception ex){}
    }
}

Server code:

import java.awt.*;
import java.net.*;
import java.nio.ByteBuffer;

public class Main{
    public static void main(String[] args) {
        try {
            DatagramSocket serverSocket = new DatagramSocket(1234);
            byte[] buff1 = new byte[256];
            byte[] buff2 = new byte[256];
            byte[] buffRezultat = new byte[256];
            while(true){
                System.out.println("Client connected.");
                DatagramPacket p1 = new DatagramPacket(buff1,buff1.length);
                DatagramPacket p2 = new DatagramPacket(buff2, buff2.length);
                serverSocket.receive(p1);
                System.out.println("p1 recieved");
                serverSocket.receive(p2);
                System.out.println("p2 recieved");
                int rezultat, brojJedan, brojDva;
                brojJedan = ByteBuffer.wrap(p1.getData()).getInt();
                brojDva = ByteBuffer.wrap(p2.getData()).getInt();
                System.out.println("byte converted to int");
                rezultat = brojJedan+brojDva;
                System.out.println("numbers added");
                buffRezultat = ByteBuffer.allocate(1).putInt(rezultat).array();
                DatagramPacket pRez = new DatagramPacket(buffRezultat, buffRezultat.length);
                serverSocket.send(pRez);
                System.out.println("res sent");
            }
        }catch(Exception ex){}

    }
}```
  • The server does contain print statements, do they get printed? Or if not, how far? – MDK Oct 18 '20 at 19:42
  • You opened an INetSocket address ep and matched the server port 1234... and then your client datagram socket is opened on port 1000? I know nothing about Datagrams right now, just wondering if that is correct addressing? –  Oct 18 '20 at 19:53
  • @MDK they get printed, all the way up to "numbers added". And then it says process finished. – Danis Jusic Oct 18 '20 at 20:06
  • @RandomCoder_01 I think it's correct. The server receives the numbers, but it doesn't return them. If I change the datagram port to 1234, the server doesn't receive any type of data. – Danis Jusic Oct 18 '20 at 20:09
  • The posted code seem to swallow exceptions. Are there any exceptions ? – SKumar Oct 18 '20 at 20:17
  • @SKumar As far as my compiler says, there isn't any. There aren't any errors, the server code doesn't work in this part: ```buffRezultat = ByteBuffer.allocate(1).putInt(rezultat).array(); DatagramPacket pRez = new DatagramPacket(buffRezultat, buffRezultat.length); serverSocket.send(pRez); System.out.println("res sent");``` – Danis Jusic Oct 18 '20 at 20:20
  • please try changing to `catch(Exception ex){ex.printStackTrace();}` and see if there any exceptions get logged at runtime. – SKumar Oct 18 '20 at 20:23
  • java.nio.BufferOverflowException at java.base/java.nio.Buffer.nextPutIndex(Buffer.java:725) at java.base/java.nio.HeapByteBuffer.putInt(HeapByteBuffer.java:446) at Main.main(Main.java:27) – Danis Jusic Oct 18 '20 at 20:45
  • @DanisJusic Could you toss that stacktrace in your question? I tried, but I'm terrible at web-app formatting –  Oct 18 '20 at 22:14
  • You got an exception when you tried to send the datagram from the sever without specifying a target address or port. ANd your code swallowed it. Don't write code like this. – user207421 Oct 18 '20 at 22:14
  • @MarquisofLorne How do I specify the target address and port? And what exactly is wrong with my code? – Danis Jusic Oct 18 '20 at 22:41
  • You specify it when you construct the datagram. Better still, reuse the datagram you received as the sending datagram: it's already in there. What is wrong with your code is that you catch `Exception` and ignore it, which prevented you from seeing this exception. – user207421 Oct 18 '20 at 23:34

1 Answers1

2

Your code contains a number of problems:

On the client side:

  1. You are putting a String into the outbound byte[] while expecting an int on the server side.

  2. You are using port 1000 with the DatagramSocket while you shouldn't use any.

  3. You are expecting a String from the inbound byte[] while putting an int into it on the server side.

On the server side:

  1. In order to receive one int (32 bits) from a byte[] you have to read four bytes (8 bits each).

  2. In order to send one ìnt via a byte[] you have to allocate four bytes.

  3. The DatagramPacket you send back from the server to the client needs to know the client's address and port.

This code works:

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.util.Scanner;

public class Client {
    public static void main(String[] args) {
        InetSocketAddress ep = new InetSocketAddress("127.0.0.1", 1234);
        String broj1, broj2;
        Scanner sc = new Scanner(System.in);
        System.out.print("Unesite 1. broj: ");
        broj1 = sc.nextLine();
        System.out.println();
        System.out.print("Unesite 2. broj: ");
        broj2 = sc.nextLine();
        if(broj1.contains("[a-zA-Z+]")&&broj2.contains("[a-zA-Z+]")){
            System.out.println("Niste unijeli brojeve.");
            System.exit(0);
        }
        byte[] brojJedan = ByteBuffer.allocate(4).putInt(Integer.parseInt(broj1)).array();
        byte[] brojDva = ByteBuffer.allocate(4).putInt(Integer.parseInt(broj2)).array();
        DatagramPacket packet1 = new DatagramPacket(brojJedan, brojJedan.length, ep);
        DatagramPacket packet2 = new DatagramPacket(brojDva, brojDva.length, ep);
        try(DatagramSocket Klijent = new DatagramSocket()){
            Klijent.send(packet1);
            Klijent.send(packet2);
            byte[] rezultat = new byte[256];
            DatagramPacket packetRezultat = new DatagramPacket(rezultat, rezultat.length, ep);
            Klijent.receive(packetRezultat);
            System.out.println(ByteBuffer.wrap(packetRezultat.getData(), 0, 4).getInt());
        }catch(Exception e){
            e.printStackTrace();
        }
    }
}


import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.nio.ByteBuffer;

public class Server {
    public static void main(String[] args) {
        try {
            DatagramSocket serverSocket = new DatagramSocket(1234);
            byte[] buff1 = new byte[256];
            byte[] buff2 = new byte[256];
            byte[] buffRezultat = new byte[256];
            while (true) {
                System.out.println("Client connected.");
                DatagramPacket p1 = new DatagramPacket(buff1, buff1.length);
                DatagramPacket p2 = new DatagramPacket(buff2, buff2.length);
                serverSocket.receive(p1);
                System.out.println("p1 recieved");
                serverSocket.receive(p2);
                System.out.println("p2 recieved");
                int rezultat, brojJedan, brojDva;
                brojJedan = ByteBuffer.wrap(p1.getData(), 0, 4).getInt();
                brojDva = ByteBuffer.wrap(p2.getData(), 0, 4).getInt();
                System.out.println("byte converted to int" + brojDva + " " + brojJedan);
                rezultat = brojJedan + brojDva;
                System.out.println("numbers added " + rezultat);
                buffRezultat = ByteBuffer.allocate(4).putInt(rezultat).array();
                DatagramPacket pRez = new DatagramPacket(buffRezultat, buffRezultat.length, p2.getAddress(), p2.getPort());
                serverSocket.send(pRez);
                System.out.println("res sent");
            }
        } catch (Exception ex) {
        }
    }
}

While this code would work (for certain input), it still does have a few weak spots:

  1. The input validation only checks if letters are not used. This does not necessarily give you a number (check out this SO post).

  2. You don't need to send two DatagramPacket s in order to transfer two int s; one is enough.

  3. Using standard I/O streams would help you writing to and reading from byte arrays.

  4. Implementing meaningful exception messages would help you write the code and users use the software.

kalabalik
  • 3,792
  • 2
  • 21
  • 50