0

im making a basic packet reciever similar to Wireshark, i tried to make a loop in which if a key is pressed, another method is called, as in the code. But my problem is that when i try to enter any method, i need to press the key and enter so fast, if not the loop makes an iteration and the key`s method isnt called. Excuse me if i made any mistake writing English.

InputStreamReader reader = new InputStreamReader(System.in);
BufferedReader in = new BufferedReader(reader);
while (true) {
    try {
        if (in.ready()) {

           s = in.readLine().toLowerCase();
           if (s.equals("f")) {
               break;
           } else if (s.equals("b")) {
               pa.borrarTabla();
               System.out.println("Tabla ARP borrada correctamente");
                } else if (s.equals("t")) {
                    paqARP.mostrarTablaARP(pa.getTablaArp());
                } else if (s.equals("m")) {
                    cc.mostrarConf(pa);
                } else if (s.equals("r")) {
                    em.enviarRangoARP();
                } else if (s.equals("c")) {
                    em.petgwydst();
                } else if (s.equals("i")) {
                    paqicmp.enviarSolicitud(em);
                }

            }

        } catch (IOException ex) {
            System.out.println("FALLO");
        }

        pa.setTablaArp(re.ejecutar(pa.getTablaArp(), em));
        try {
            Thread.sleep(20);
        } catch (InterruptedException ex) {
        }
    }
Xolopo
  • 1
  • 1
  • 5
    Do you actually need the `in.ready()` check? `in.readLine()` would block until it's ready. – Andy Turner Apr 16 '20 at 16:01
  • Yes I need, because the loop stops until a key is entered, ```in.readLine()``` doesnt seem to block until it's ready – Xolopo Apr 16 '20 at 16:09
  • 1
    If you want to read just a single character, don't ask for a whole line: `in.read()` would give you a single character. – Andy Turner Apr 16 '20 at 16:12
  • Not looking for efficiency yet – Xolopo Apr 16 '20 at 16:25
  • How are you determining this "enter any method, i need to press the key and enter so fast, if not the loop makes an iteration and the key`s method isnt called." – matt Apr 16 '20 at 16:29
  • Well, im trying to enter a key, and the program calls a method depending on they key, but when i try to make this, the program keeps running – Xolopo Apr 16 '20 at 16:31
  • System.in won't return anything until you press enter. At which point ready will be true and readLine will return immediately. You don't need to press the key then enter in rapid succession. – matt Apr 16 '20 at 16:34
  • Maybe this is what you're looking for? https://stackoverflow.com/questions/1864076/equivalent-function-to-cs-getch-in-java – matt Apr 16 '20 at 16:36
  • Also, BufferedReader.readLine blocks. Did you close your System.in? – matt Apr 16 '20 at 16:39
  • .ready() should be true, when System.in() has something, i mean when you type something without pressing enter, so it should work correctly – Xolopo Apr 16 '20 at 16:51
  • That is not the case. Your bufferedreader will not be ready until you have pressed enter since you're using system.in. – matt Apr 16 '20 at 16:54

1 Answers1

0

Here is a complete example to test some of your hypothesis.

import java.io.*;
public class BuffReady{

    public static void main(String[] args) throws Exception{
        BufferedReader in = new BufferedReader( new InputStreamReader(System.in));
        System.out.println("started waiting");
        String first = in.readLine();
        System.out.println("started loop");
        while(true){
            if(in.ready()){
                System.out.println( "read: " + in.readLine() );
            } 
            Thread.sleep(1000);
            System.out.println(" passed: " + in.ready());
        }
    }
}

What you will find, the first readLine blocks and you wait there until enter is pressed. Then in the loop, ready() will return false until you press enter, even if you type other input.

matt
  • 10,892
  • 3
  • 22
  • 34
  • Yes, thats what i mean, but i need to type the key and enter before a loop iteration. https://imgur.com/a/c1BpFEv if you type and then wait 1-2 iterations (my loop needs to be fast to catch all packets), then it doesnt read the key well – Xolopo Apr 16 '20 at 17:06
  • This doesn't return anything until you hit enter. So you press 'm' and ready() continues to return false, then you press enter and ready() is true and readline returns immediately. It doesn't read the key, it reads ready() and readLine() when you press enter. – matt Apr 16 '20 at 17:12
  • But i hit enter, look at the space between the passed:false and passed:true – Xolopo Apr 16 '20 at 17:15
  • Right, you hit enter, the next time 'ready' is called, it returns true, then it enters the readLine clause and that immediately returns with m then you continue. – matt Apr 16 '20 at 17:21
  • You probably hit enter while the Thread is sleeping, as that is where this loop will spend 99% of it's time. – matt Apr 16 '20 at 17:22