java - TCPDump-Buffer 上的 ReadLine 有时会阻塞,直到终止 tcpdump

标签 java android tcpdump

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

public class ListenActivity extends Activity {

static ArrayList<Packet> packetBuffer = new ArrayList<Packet>();
static Process tcpDumpProcess = null;
static ListenThread thread = null;
public static final String TCPDUMP_COMMAND = "tcpdump -A -s0 | grep -i -e 'Cookie'\n";

private InputStream  inputStream = null;
private OutputStream outputStream = null;

@Override
protected void onStart() {
    super.onStart();
    try {
        tcpDumpProcess = new ProcessBuilder().command("su").redirectErrorStream(true).start();
        inputStream = tcpDumpProcess.getInputStream();
        outputStream = tcpDumpProcess.getOutputStream();
        outputStream.write(TCPDUMP_COMMAND.getBytes("ASCII"));
    } catch (Exception e) {
        Log.e("FSE", "", e);
    }
    thread = new ListenThread(new BufferedReader(new InputStreamReader(inputStream)));
    thread.start();
}

private class ListenThread extends Thread {

    public ListenThread(BufferedReader reader) {
        this.reader = reader;
    }

    private BufferedReader reader = null;

    @Override
    public void run() {

        reader = new BufferedReader(new InputStreamReader(inputStream));
        while (true) {
            try {                   
                String received = reader.readLine();
                Log.d("FS", received);
                Packet pReceived = Packet.analyze(received);
                if (pReceived != null) {
                    packetBuffer.add(pReceived);
                }
            } catch (Exception e) {
                Log.e("FSE", "", e);
            }

        }

    }

}

最佳答案

因为发送到管道的输出通常是 block 缓冲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''.

对于 grep(1):

   --line-buffered
          Use line buffering on output.  This can cause a
          performance penalty.

试试这个:

"tcpdump -l -A -s0 | grep --line-buffered -i -e 'Cookie'\n";

关于java - TCPDump-Buffer 上的 ReadLine 有时会阻塞,直到终止 tcpdump,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5714875/

相关文章:

java - 在 Scala 中为 Java 对象创建隐式 View 的最佳方法

android - Phone Auth 自动验证在 Flutter Firebase 中不起作用

android - 模拟错误 -"there were zero interactions with this mock"

linux - shell 脚本中的 tcpdump 没有捕获任何内容

java - HttpSession.invalidate() 和 TCPDUMP

java - 如何在 Java 中有条件地调用不同的构造函数?

java - 编译成java字节码(不使用Java)

linux自动接收所有组播流量

java - 使用 sax 解析 xml 响应

java - 使用 opencv (Java) 的阈值图像