简体   繁体   English

如何在Java中运行tshark以实时获取数据包?

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

I have a problem with running tshark in Java. 我在Java中运行tshark时遇到问题。 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? 还尝试使用InputStream的available()方法,如InputStream.available()在Java中的功能所示?

I also tried NuProcess library with the following code: 我还尝试了使用以下代码的NuProcess库:

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. 仅在嗅探到大约50个数据包时,它们才总是到达(就像缓冲一样)。

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. 我在SO上花了很多时间研究类似的问题,但没有一个有帮助。

Do you see any errors in my code? 您在我的代码中看到任何错误吗? Is it working in your case? 在您的情况下有效吗?

As the tshark man page says: 正如tshark手册页所述:

   −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. 尝试使用-l命令行参数运行tshark。

I ran some tests to see how much Buffering would be done by BufferedReader versus just using the input stream. 我进行了一些测试,以查看BufferedReader与仅使用输入流相比将完成多少缓冲。

        ProcessBuilder pb = new ProcessBuilder("ls", "-lR", "/");

        System.out.println("pb.command() = " + pb.command());

        Process p = pb.start();
        byte ba[] = new byte[100];
        InputStream is = p.getInputStream();
        int bytecountsraw[] = new int[10000];
        long timesraw[] = new long[10000];
        long last_time = System.nanoTime();
        for (int i = 0; i < timesraw.length; i++) {
            int bytecount = is.read(ba);
            long time = System.nanoTime();
            timesraw[i] = time - last_time;
            last_time = time;
            bytecountsraw[i] = bytecount;
        }
        try (PrintWriter pw = new PrintWriter(new FileWriter("dataraw.csv"))) {
            pw.println("bytecount,time");
            for (int i = 0; i < timesraw.length; i++) {
                pw.println(bytecountsraw[i] + "," + timesraw[i] * 1.0E-9);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        BufferedReader br = new BufferedReader(new InputStreamReader(is));
        int bytecountsbuffered[] = new int[10000];
        long timesbuffered[] = new long[10000];
        last_time = System.nanoTime();
        for (int i = 0; i < timesbuffered.length; i++) {
            String str = br.readLine();
            int bytecount = str.length();
            long time = System.nanoTime();
            timesbuffered[i] = time - last_time;
            last_time = time;
            bytecountsbuffered[i] = bytecount;
        }
        try (PrintWriter pw = new PrintWriter(new FileWriter("databuffered.csv"))) {
            pw.println("bytecount,time");
            for (int i = 0; i < timesbuffered.length; i++) {
                pw.println(bytecountsbuffered[i] + "," + timesbuffered[i] * 1.0E-9);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

I tried to find a command that would just keep printing as fast as it could so that any delays would be due to the buffering and/or ProcessBuilder rather than in the command itself. 我试图找到一个命令,该命令将保持尽可能快的打印速度,以使所有延迟都归因于缓冲和/或ProcessBuilder,而不是命令本身。 Here is a plot of the result. 这是结果图。

原始和缓冲时间图

You can plot the csv files with excel although I used a Netbeans plugin called DebugPlot. 尽管我使用了一个名为DebugPlot的Netbeans插件,但是可以使用excel绘制csv文件。 There wasn't a great deal of difference between the raw and the buffered. 原始缓冲区和缓冲缓冲区之间没有太大区别。 Both were bursty with majority of reads taking less than a microsecond separated by peaks of 10 to 50 milliseconds. 两者都是突发性的,大多数读取花费不到10微秒(由10到50毫秒的峰值分隔)。 The scale of the plot is in nanoseconds so the top of 5E7 is 50 milliseconds or 0.05 seconds. 图的比例尺以纳秒为单位,因此5E7的顶部为50毫秒或0.05秒。 If you test and get similar results perhaps it is the best process builder can do. 如果您测试并获得相似的结果,那么也许这是最好的过程构建者可以做的。 If you get dramatically worse results with tshark than other commands, perhaps there is an option to tshark or the packets themselves are coming in bursts. 如果使用tshark比其他命令得到的结果明显更糟,则可能是tshark的一个选项,否则数据包本身会突然爆发。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM