Search code examples
javareal-timeinputstreambufferingtshark

How to run tshark in Java to get packets in real-time?


I have a problem with running tshark in Java. It seems that packets arrive in bulk instead of truly real-time (as it happens when run from terminal). I tried a few different approaches:

ArrayList<String> command = new ArrayList<String>();
command.add("C:\\Program Files\\Wireshark\\tshark.exe");
ProcessBuilder pb = new ProcessBuilder(command);
Process process = pb.start();

BufferedReader br = null;
try {
    //tried different numbers for BufferedReader's last parameter
    br = new BufferedReader(new InputStreamReader(process.getInputStream()), 1);
    String line = null;
    while ((line = br.readLine()) != null) {
        System.out.println(line);
    }
} catch...

also tried using InputStream's available() method as seen in What does InputStream.available() do in Java?

I also tried NuProcess library with the following code:

NuProcessBuilder pb = new NuProcessBuilder(command);
ProcessHandler processHandler = new ProcessHandler();
pb.setProcessListener(processHandler);
NuProcess process = pb.start();
try {
    process.waitFor(0, TimeUnit.SECONDS);
} catch (InterruptedException e) {
    e.printStackTrace();
}

private class ProcessHandler extends NuAbstractProcessHandler {
    private NuProcess nuProcess;

    @Override
    public void onStart(NuProcess nuProcess) {
        this.nuProcess = nuProcess;
    }

    @Override
    public void onStdout(ByteBuffer buffer) {
        if (buffer == null)
            return;

        byte[] bytes = new byte[buffer.remaining()];
        buffer.get(bytes);
        System.out.println(new String(bytes));
    }
}

None of the methods work. Packets always arrive, as if buffered, only when about 50 were sniffed.

Do you have any idea why this may be happening and how to solve it? It's pretty frustrating. I spent a lot of time looking at similar questions at SO, but none of them helped.

Do you see any errors in my code? Is it working in your case?


Solution

  • As the tshark man page says:

       −l  Flush the standard output after the information for each packet is
           printed.  (This is not, strictly speaking, line‐buffered if −V was
           specified; however, it is the same as line‐buffered if −V wasn’t
           specified, as only one line is printed for each packet, and, as −l
           is normally used when piping a live capture to a program or script,
           so that output for a packet shows up as soon as the packet is seen
           and dissected, it should work just as well as true line‐buffering.
           We do this as a workaround for a deficiency in the Microsoft Visual
           C++ C library.)
    
           This may be useful when piping the output of TShark to another
           program, as it means that the program to which the output is piped
           will see the dissected data for a packet as soon as TShark sees the
           packet and generates that output, rather than seeing it only when
           the standard output buffer containing that data fills up.
    

    Try running tshark with the -l command-line argument.