Android adb forward转发TCP端口连接数据

289 篇文章 7 订阅

Android adb的一个命令 : adb forward,该命令转发PC电脑上的端口数据到Android设备的一个端口。

adb forward tcp:18000 tcp:19000

上面的命令,即把PC电脑端TCP端口18000的数据转发到与电脑通过adb连接的Android设备的TCP端口19000上。换言之,假设现在PC端在端口18000绑定,并在该端口读写数据,将会被转发到Android设备端的19000。

写一个例子,假设现在PC端作为客户端,用Java普通Socket写一个客户端绑定端口18000,并在这个端口写入和读取数据,然后Android作为服务器端绑定端口19000,等待客户端连接。服务器端与客户端建立连接后,两者进行数据的IO。

客户端(PC):

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.net.Socket;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.logging.Logger;

public class SocketTest {
	private ScheduledThreadPoolExecutor mScheduledThreadPoolExecutor = null;
	private Runnable mRunnable = null;
	private ScheduledFuture<?> mScheduledFuture = null;
	private Socket mSocket = null;

	private Logger mLogger = Logger.getLogger(SocketTest.class.getName());

	private void session() {
		DataInputStream dis = null;
		DataOutputStream dos = null;
		try {
			dis = new DataInputStream(mSocket.getInputStream());
			dos = new DataOutputStream(mSocket.getOutputStream());

			while (true) {
				String data = "PC时间:" + System.currentTimeMillis();
				dos.writeUTF(data);
				dos.flush();

				String s = dis.readUTF();
				mLogger.info("收到数据:" + s);

				Thread.sleep(5000);
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				mSocket.close();
			} catch (Exception e) {
				e.printStackTrace();
			}

			mSocket = null;
		}
	}

	public SocketTest() {
		mScheduledThreadPoolExecutor = new ScheduledThreadPoolExecutor(1);

		mRunnable = new Runnable() {
			@Override
			public void run() {
				if (mSocket == null || !mSocket.isConnected()) {
					mLogger.info("尝试建立连接...");
					try {
						mSocket = new Socket("localhost", 18000);
						mLogger.info("建立新连接:" + mSocket.toString());

						CompletableFuture.runAsync(new Runnable() {
							@Override
							public void run() {
								session();
							}
						});
					} catch (Exception e) {
						mLogger.info("连接异常");
					}
				} else {
					mLogger.info("连接心跳检测:当前已经建立连接,无需重连");
				}
			}
		};

		// 每隔3秒周期性的执行心跳检测动作。
		mScheduledFuture = mScheduledThreadPoolExecutor.scheduleAtFixedRate(mRunnable, 0, 3, TimeUnit.SECONDS);
	}

	public static void main(String[] args) {
		new SocketTest();
	}
}

 

服务器端(Android):

package zhangphil.socket;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;


public class MainActivity extends AppCompatActivity {
    private String TAG = "Android端";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        new ServerThread().start();
    }

    private class ServerThread extends Thread {

        @Override
        public void run() {
            ServerSocket serverSocket = null;
            try {
                serverSocket = new ServerSocket(19000);
                while (true) {
                    Socket socket = serverSocket.accept();
                    Log.d(TAG, "接受连接");

                    new ClientThread(socket).start();
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if (serverSocket != null) {
                    try {
                        serverSocket.close();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }

    private class ClientThread extends Thread {
        private Socket socket;

        public ClientThread(Socket socket) {
            this.socket = socket;
            Log.d(TAG, "当前Socket:" + socket.toString());
        }

        @Override
        public void run() {
            try {
                DataInputStream dis = new DataInputStream(socket.getInputStream());
                DataOutputStream dos = new DataOutputStream(socket.getOutputStream());

                while (true) {

                    String data = dis.readUTF();
                    Log.d(TAG, "收到数据:" + data);

                    //回写给客户端。
                    String s = "手机时间:" + System.currentTimeMillis();
                    dos.writeUTF(s);
                    dos.flush();
                }

            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                try {
                    socket.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

 

adb forward是市面上流行的xx手机助手的底层关键技术。注意,当手机端在反复切换USB连接模式(充电,传输文件等模式),会导致adb断开,进而直接导致上层的Socket连接失败。每次USB连接模式改变后,需要重新使用adb forward命令:

adb forward tcp:18000 tcp:19000

同时要保证手机处于开发者模式,且已打开debug调试模式。

  • 9
    点赞
  • 37
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zhangphil

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值