TCPDump-Buffer 上的 ReadLine 有时会阻塞,直到杀死 tcpdump
我在 Android 应用程序中使用 TCPDump 时遇到问题。 它应该逐行读取 tcpdump 的输出并在我的应用程序中处理它。
问题是:
有时代码工作正常,它会立即读取捕获的数据包。但有时,ReadLine 会阻塞,直到我从 Linux 控制台终止 tcpdump 进程(killall 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);
}
}
}
}
}
I have a problem using TCPDump from my Android-Application.
It is supposed to read the output from tcpdump line by line and process it within my Application.
The Problem is:
Sometimes the code works fine, it reads the captured packets immediately. But sometimes, ReadLine blocks until I kill the tcpdump process from the Linux-Console (killall tcpdump). After doing that, my loop is processed for each line (sometimes 10, sometimes 1 or 2) - which means, the readLine should have worked, but didn´t.
I read about similar problems, but did not find any solution for this problem...
THANKS!!
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);
}
}
}
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
由于发送到管道的输出通常是块缓冲的,因此
tcpdump
进程和 grep 进程都将等待,直到他们已收到足够的数据,无需将其发送到您的程序中。 ,您很幸运,您选择使用的两个程序都准备修改其缓冲区行为(在内部使用setvbuf(3)
函数,以防您对细节感到好奇):不过
tcpdump(8)
:对于
grep(1)
:试试这个:
Because output sent to pipes is usually block buffered, both the
tcpdump
process and thegrep
process will be waiting until they've received enough data to bother sending it onto your program. You're very lucky though, both programs you have chosen to use are prepared to modify their buffer behavior (using thesetvbuf(3)
function internally, in case you're curious about the details):For
tcpdump(8)
:For
grep(1)
:Try this:
我不明白为什么,但即使使用 -l 选项,如果您读取运行 tcpdump 的进程的标准输出,缓冲区也会太大。
我通过将 TcpDump 的输出重定向到一个文件并在另一个线程中读取该文件来解决这个问题。 TcpDump 命令应该类似于:
线程内的 run 方法必须更改为在输出文件中读取:
我不完全知道你想用 grep 做什么,但我认为可以使用内部的 regexp 实现相同的操作Java 代码。
您还应该注意,TcpDump 的进程永远不会结束,因此您必须在活动暂停或销毁时终止它。
您可以查看这里在我的博客文章中,我解释了启动/停止 tcpdump 的整个代码。
I don't understand why, but even with the -l option the buffer is too large if you read on the standard output of the process wherein you run tcpdump.
I solve this problem by redirect TcpDump's output to a file and read this file in another thread. The TcpDump command should be something like :
The run method inside your thread have to be change to read in the output file :
I dont exactly know what you want to do with grep but I think it's possible do achieve the same actions with a regexp inside the Java code.
You should also be aware that the TcpDump's process will never end, so you have to kill it when your activity is paused or distroy.
You can have a look here to my blog post, I explain my whole code to start/stop tcpdump.