2

AndroidアプリケーションからTCPDumpを使用する際に問題が発生しました。tcpdumpからの出力を1行ずつ読み取り、アプリケーション内で処理することになっています。
問題は次
のとおりです。コードが正常に機能する場合があり、キャプチャされたパケットをすぐに読み取ります。しかし、Linuxコンソールからtcpdumpプロセスを強制終了するまでReadLineがブロックされることがあります(killalltcpdump)。それを行った後、私のループは各行(場合によっては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);
            }

        }

    }

}

}

4

2 に答える 2

4

通常、パイプに送信される出力はブロック バッファリングされるため、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";
于 2011-04-19T10:25:40.400 に答える
0

理由はわかりませんが、-l オプションを使用しても、tcpdump を実行するプロセスの標準出力を読み取ると、バッファーが大きすぎます。この問題を解決するには、TcpDump の出力をファイルにリダイレクトし、このファイルを別のスレッドで読み取ります。TcpDump コマンドは次のようになります。

tcpdump -l-A -s0 > /data/local/output.txt

スレッド内の run メソッドは、出力ファイルを読み取るように変更する必要があります。

File dumpedFile = new File("/data/local/output.txt");
//open a reader on the tcpdump output file
BufferedReader reader = new BufferedReader(new FileReader(dumpedFile));
String temp = new String();
//The while loop is broken if the thread is interrupted   
while (!Thread.interrupted()) {    
    temp = reader.readLine();
    if (temp!=null) {
        Log.e("READER",new String(temp));    
    }
}

あなたがgrepで何をしたいのか正確にはわかりませんが、Javaコード内の正規表現で同じアクションを達成できると思います。

また、TcpDump のプロセスは決して終了しないことに注意する必要があります。そのため、アクティビティが一時停止または破棄された場合は強制終了する必要があります。こちらのブログ投稿をご覧ください。tcpdump を開始/停止するためのコード全体を説明しています。

于 2011-06-01T22:35:08.927 に答える