2015-08-11 4 views
1

У меня проблема с запуском tshark в Java. Кажется, что пакеты поступают навалом, а не в реальном времени (как это происходит при запуске с терминала). я попробовал несколько различных подходов:Как запустить tshark в Java для получения пакетов в режиме реального времени?

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... 

также попытался с помощью метода InputStream в доступной(), как показано на What does InputStream.available() do in Java?

Я также попытался библиотеку 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)); 
    } 
} 

Ни один из методы работают. Пакеты всегда поступают, как если бы они буферизовались, только когда около 50 были обнюханы.

У вас есть идеи, почему это может произойти и как его решить? Это довольно неприятно. Я потратил много времени на подобные вопросы в SO, но никто из них не помог.

Вы видите ошибки в моем коде? Это работает в вашем случае?

+0

Java обрабатывает выходные данные (и ввод) дочернего процесса, используя каналы, и множество программ на C, включая 'tshark', буфер при записи в канал. Попытка исправить это на стороне чтения Java слишком поздно. См. Http://unix.stackexchange.com/questions/72428/cant-process-stdout-with-pipe-as-it-comes и, в частности, самый простой ответ: укажите параметр '-l' для' tshark'. –

+0

это решило мою проблему :) спасибо – illus2003

ответ

1

Как страница человека 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. 

Попробуйте запустить tshark с -l аргументом командной строки.

0

Я провел несколько тестов, чтобы узнать, сколько буферизации будет сделано 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(); 
     } 

Я пытался найти команду, которая будет просто держать печать так быстро, как это могло так, что любые задержки будет связано с буферизацией и/или ProcessBuilder, а не в самой команде. Вот график результата.

plot of times raw and buffered

Вы можете построить файлы CSV с Excel, хотя я использовал плагин Netbeans под названием DebugPlot. Между исходным и буферизированным не было большой разницы. Оба из них были взрывоопасны, большинство из них читали менее микросекунды, разделенные пиками от 10 до 50 миллисекунд. Шкала графика находится в наносекундах, поэтому верхняя часть 5E7 составляет 50 миллисекунд или 0,05 секунды. Если вы проверите и получите похожие результаты, возможно, это лучший строитель процесса. Если вы получаете значительно худшие результаты с tshark, чем другие команды, возможно, есть опция tshark или сами пакеты попадают в пакеты.