TCPDump-Buffer 上的 ReadLine 有时会阻塞,直到杀死 tcpdump

and*_*911 3 java android tcpdump

我在 Android 应用程序中使用 TCPDump 时遇到问题。\n它应该逐行读取 tcpdump 的输出并在我的应用程序中处理它。
问题是:
有时代码工作正常,它会立即读取捕获的数据包。但有时,ReadLine 会阻塞,直到我从 Linux 控制台终止 tcpdump 进程(killall tcpdump)。这样做之后,我的循环会针对每一行进行处理(有时是 10 行,有时是 1 或 2 行) - 这意味着 readLine 应该有效,但没有 \xc2\xb4t。\n \n我读到了
类似的问题,但没有找到这个问题的任何解决方案...
谢谢!

\n\n
public class ListenActivity extends Activity {\n\nstatic ArrayList<Packet> packetBuffer = new ArrayList<Packet>();\nstatic Process tcpDumpProcess = null;\nstatic ListenThread thread = null;\npublic static final String TCPDUMP_COMMAND = "tcpdump -A -s0 | grep -i -e \'Cookie\'\\n";\n\nprivate InputStream  inputStream = null;\nprivate OutputStream outputStream = null;\n\n@Override\nprotected void onStart() {\n    super.onStart();\n    try {\n        tcpDumpProcess = new ProcessBuilder().command("su").redirectErrorStream(true).start();\n        inputStream = tcpDumpProcess.getInputStream();\n        outputStream = tcpDumpProcess.getOutputStream();\n        outputStream.write(TCPDUMP_COMMAND.getBytes("ASCII"));\n    } catch (Exception e) {\n        Log.e("FSE", "", e);\n    }\n    thread = new ListenThread(new BufferedReader(new InputStreamReader(inputStream)));\n    thread.start();\n}\n\nprivate class ListenThread extends Thread {\n\n    public ListenThread(BufferedReader reader) {\n        this.reader = reader;\n    }\n\n    private BufferedReader reader = null;\n\n    @Override\n    public void run() {\n\n        reader = new BufferedReader(new InputStreamReader(inputStream));\n        while (true) {\n            try {                   \n                String received = reader.readLine();\n                Log.d("FS", received);\n                Packet pReceived = Packet.analyze(received);\n                if (pReceived != null) {\n                    packetBuffer.add(pReceived);\n                }\n            } catch (Exception e) {\n                Log.e("FSE", "", e);\n            }\n\n        }\n\n    }\n\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

}

\n

sar*_*old 5

因为发送到管道的输出通常是块缓冲的,所以tcpdump进程进程grep都会等待,直到它们收到足够的数据才能将其发送到您的程序。不过,您很幸运,您选择使用的两个程序都准备修改其缓冲区行为(setvbuf(3)在内部使用该函数,以防您对细节感到好奇):

为了tcpdump(8)

   -l     Make stdout line buffered.  Useful if you want to see
          the data while capturing it.  E.g.,
          ``tcpdump  -l  |  tee dat'' or ``tcpdump  -l   >
          dat  &  tail  -f  dat''.
Run Code Online (Sandbox Code Playgroud)

为了grep(1)

   --line-buffered
          Use line buffering on output.  This can cause a
          performance penalty.
Run Code Online (Sandbox Code Playgroud)

尝试这个:

"tcpdump -l -A -s0 | grep --line-buffered -i -e 'Cookie'\n";
Run Code Online (Sandbox Code Playgroud)