Android应用很多时候都会涉及到网络,在请求网络出错时,我们可以通过抓包来分析网络请求,返回的数据等,通常我们是用tcpdump这个工具来抓包,再通过wireshark工具来分析生成的文件,关于tcpdump的使,可以从网上查一下,有很多介绍,比如:http://www.cnblogs.com/likwo/archive/2012/09/06/2673944.html。关于如何用wireshark来分析文件,本文不作介绍。

使用adb的命令来操作,还是比较麻烦,所以我写了一个应用,把这些命令封装了起来。实现的最根本的原理是通过Runtime.exec来执行linux命令。

运行截图

实现代码

CommandsHelper.java
/**
*
* @author lihong06
* @since 2014-3-3
*/
public class CommandsHelper {
private static final String NAME = "tcpdump";
private static final String TAG = "CommandsHelper";
public static final String DEST_FILE = Environment.getExternalStorageDirectory() + "/capture.pcap"; public static boolean startCapture(Context context) {
InputStream is = null;
OutputStream os = null;
boolean retVal = false;
try {
AssetManager am = context.getAssets();
is = am.open(NAME);
File sdcardFile = Environment.getExternalStorageDirectory();
File dstFile = new File(sdcardFile, NAME);
os = new FileOutputStream(dstFile); copyStream(is, os); String[] commands = new String[7];
commands[0] = "adb shell";
commands[1] = "su";
commands[2] = "cp -rf " + dstFile.toString() + " /data/local/tcpdump";
commands[3] = "rm -r " + dstFile.toString();
commands[4] = "chmod 777 /data/local/tcpdump";
commands[5] = "cd /data/local";
commands[6] = "tcpdump -p -vv -s 0 -w " + DEST_FILE; execCmd(commands);
} catch (IOException e) {
e.printStackTrace();
Log.i(TAG, " error: " + e.getMessage());
} finally {
closeSafely(is);
closeSafely(os);
} return retVal;
} public static void stopCapture(Context context) {
// 找出所有的带有tcpdump的进程
String[] commands = new String[2];
commands[0] = "adb shell";
commands[1] = "ps|grep tcpdump|grep root|awk '{print $2}'";
Process process = execCmd(commands);
String result = parseInputStream(process.getInputStream());
if (!TextUtils.isEmpty(result)) {
String[] pids = result.split("\n");
if (null != pids) {
String[] killCmds = new String[pids.length];
for (int i = 0; i < pids.length; ++i) {
killCmds[i] = "kill -9 " + pids[i];
}
execCmd(killCmds);
}
}
} public static Process execCmd(String command) {
return execCmd(new String[] { command }, true);
} public static Process execCmd(String[] commands) {
return execCmd(commands, true);
} public static Process execCmd(String[] commands, boolean waitFor) {
Process suProcess = null;
try {
suProcess = Runtime.getRuntime().exec("su");
DataOutputStream os = new DataOutputStream(suProcess.getOutputStream());
for (String cmd : commands) {
if (!TextUtils.isEmpty(cmd)) {
os.writeBytes(cmd + "\n");
}
}
os.flush();
os.writeBytes("exit\n");
os.flush();
} catch (IOException e) {
e.printStackTrace();
} if (waitFor) {
boolean retval = false;
try {
int suProcessRetval = suProcess.waitFor();
if (255 != suProcessRetval) {
retval = true;
} else {
retval = false;
}
} catch (Exception ex) {
Log.w("Error ejecutando el comando Root", ex);
}
} return suProcess;
} private static void copyStream(InputStream is, OutputStream os) {
final int BUFFER_SIZE = 1024;
try {
byte[] bytes = new byte[BUFFER_SIZE];
for (;;) {
int count = is.read(bytes, 0, BUFFER_SIZE);
if (count == -1) {
break;
} os.write(bytes, 0, count);
}
} catch (IOException e) {
e.printStackTrace();
}
} private static void closeSafely(Closeable is) {
try {
if (null != is) {
is.close();
}
} catch (IOException e) {
e.printStackTrace();
}
} private static String parseInputStream(InputStream is) {
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String line = null;
StringBuilder sb = new StringBuilder();
try {
while ( (line = br.readLine()) != null) {
sb.append(line).append("\n");
}
} catch (IOException e) {
e.printStackTrace();
} return sb.toString();
}
}

MainActivity.java

public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); final TextView textView = (TextView) findViewById(R.id.textView1);
String oldText = textView.getText().toString();
textView.setText(oldText + "\n\n" + "目标文件: " + CommandsHelper.DEST_FILE); findViewById(R.id.start_capture).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
v.setEnabled(false);
new Thread(new Runnable() {
@Override
public void run() {
final boolean retVal = CommandsHelper.startCapture(MainActivity.this);
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(MainActivity.this, "startCapture result = " + retVal, Toast.LENGTH_SHORT).show();
}
});
}
}).start();
}
}); findViewById(R.id.stop_capture).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
CommandsHelper.stopCapture(MainActivity.this);
findViewById(R.id.start_capture).setEnabled(true);
}
});
} @Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}

说明

1、手机必须要Root,没有root的我没有测试过,另外,我也只测试了我一台手机,没有覆盖到所有的手机。
2、大家如果发现问题,请告知于我,谢谢。

Android tcpdump抓包应用实现的更多相关文章

  1. Android常用抓包工具之TcpDump

    ➠更多技术干货请戳:听云博客 做为一个测试人员,工作中经常会用到数据抓包工具来进行数据分析和验证,下面就简单介绍一下工作中常用的抓包工具. TcpDump抓包 Tcpdump是一个用于截取网络分组,并 ...

  2. [转] Android利用tcpdump抓包

    原文链接:http://mysuperbaby.iteye.com/blog/902201 Android利用tcpdump抓包 博客分类: Android AndroidAccessGoHTML  ...

  3. Android手机tcpdump抓包

    在开发过程中遇到问题时,无法非常方便的获取到数据包,导致分析解决问题比较麻烦.这里介绍如何在Android手机上实现tcpdump抓包.   1.root机器  在用tcpdump抓包过程中,需要使用 ...

  4. Android利用tcpdump抓包,用wireshark分析包。

    1.前言 主要介绍在android手机上如何利用tcpdump抓包,用wireshark分析包. android tcpdump官网: http://www.androidtcpdump.com/ t ...

  5. Android 常用抓包工具介绍之Charles

    ➠更多技术干货请戳:听云博客 Charles是一款抓包修改工具,相比起TcpDump,charles具有界面简单直观,易于上手,数据请求控制容易,修改简单,抓取数据的开始暂停方便等等优势!前面介绍了如 ...

  6. [转] Android实时抓包分析 : 善用adb调试桥

    Android实时抓包分析 : 善用adb调试桥   谈到android网络抓包,很多人都能想到牛逼轰轰的神器tcpdump.方法就是在android机器上面安装tcpdump,然后通过-w参数把抓包 ...

  7. tcpdump抓包命令

    本文转自 : http://www.cnblogs.com/ggjucheng/archive/2012/01/14/2322659.html http://www.itshouce.com.cn/l ...

  8. TCPdump抓包命令详解--摘

    http://blog.csdn.net/s_k_yliu/article/details/6665673/ http://starsliao.blog.163.com/blog/static/890 ...

  9. Wireshark和TcpDump抓包分析心得

    Wireshark和 TcpDump抓包分析心得  1. Wireshark与tcpdump介绍 Wireshark是一个网络协议检测工具,支持Windows平台和Unix平台,我一般只在Window ...

随机推荐

  1. 关于C++数组的几点讨论

    数组名为何物? int main() { , , , , }; int *pnumber = number; cout << sizeof(number) << endl; c ...

  2. 用python写刷票程序

    刷票一般要突破以下限制: 1.验证码识别 2.同一ip不可连续投票 解决办法 1.用tesseract工具,链接在此 https://code.google.com/p/tesseract-ocr/  ...

  3. VBS自编写脚本。(实现批量修改文件名且在执行前,备份原有文件夹中的文件)

    '=========================================================================='' VBScript Source File - ...

  4. 第十六节,基本数据类型,字典dict

    字典 常用操作: 索引 新增 删除 键.值.键值对 循环 长度 字典由键值对组成,由一个键(名称)和 一个值组成,与列表和元组不同的是里面的元素是有键的(名称) 所以当要打印字典时,打印字典变量加[键 ...

  5. JavaScript在智能手机上的应用-通过滑动修改网页字体大小

    ---------------------------------- <script type="text/javascript">            //变量x, ...

  6. JavaScript在智能手机上的应用-用手势来改变图片大小

    ---------------------------------- <script type="text/javascript">            //初始化函 ...

  7. data Mining with Weka: Trailer More Data Mining with Weka 用weka 进行数据挖掘 Weka 用weka 进行更多数据挖掘

    https://www.youtube.com/user/WekaMOOC 大学公开课  视频教程 weka 入门教程 data Mining with Weka: Trailer  More Dat ...

  8. ios控件 UIImageView

    UIImageView的作用是显示图片和多张动态的图片   - (id)initWithImage:(UIImage *)image;//初始化图片视图 - (id)initWithImage:(UI ...

  9. iOS中静态库-.a文件生成和使用

    最近在使用使用一个网上的Demo的时候. 出现另一令人烦恼的问题 . 就是它里面有嵌套的工程. 如下图所示. 工程里面还嵌套有一个工程. 真的是让人煞费苦心 …其实这个问题看起来并不是很难, 如果是一 ...

  10. React和动态网站接口的经济学

    来自: React and the economics of dynamic web interfaces 自从2000开始我就一直在做web开发,曾见过很多以各种库和框架的起起落落,这些库和框架作为 ...