PC通过USB连接Android通信(Socket)
2016-11-18 17:47
316 查看
Android端Socket服务器
/**
* Created by Jack Stone on 2016/11/17.
* Socket服务器,PC可以通过USB连接、ADB端口映射连接本服务器,不需要通过Wifi和网络
*/
public class TCPConnect implements Runnable {
private static final String TAG = "TCPConnect";
private final int SERVER_PORT = 10086;
private ServerSocket mServerSocket;
private Socket mClient;
private Callback callback;
public TCPConnect(Callback callback) {
this.callback = callback;
}
@Override
public void run() {
try {
String ip = InetAddress.getLocalHost().getHostAddress();
mServerSocket = new ServerSocket(SERVER_PORT);
callback.call("建立服务器:[" + ip + ":" + SERVER_PORT + "]");
} catch (IOException e) {
callback.call("建立服务器异常:" + e.getMessage());
}
while (true) {
BufferedOutputStream out = null;
BufferedReader in = null;
try {
mClient = mServerSocket.accept();
callback.call("建立链接:" + mClient.getInetAddress().toString() + ":" + mClient.getPort());
out = new BufferedOutputStream(mClient.getOutputStream());
in = new BufferedReader(new InputStreamReader(mClient.getInputStream()));
String request = receive(in);
callback.call("client:"+request);
send(out, request);
} catch (IOException e) {
Log.e(TAG, "run: ", e);
callback.call(e.getMessage());
} finally {
close(out);
close(in);
close(mClient);
}
}
}
private void send(OutputStream out, String msg) throws IOException {
msg += "\n";
out.write(msg.getBytes("utf-8"));
}
private String receive(BufferedReader in) throws IOException {
String r = in.readLine();
callback.call("origin request:"+r);
if(r.contains("\\&")) {
callback.call("进行\\&替换!");
r = r.replaceAll("\\\\&","\n");
}
return r;
}
private void close(OutputStream out) {
if (out != null) {
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
private void close(BufferedReader in) {
if (in != null) {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
private void close(Socket socket) {
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
Log.e(TAG, "run: ", e);
}
}
}
public interface Callback {
void call(String msg);
}
}
PC客户端
using CMDExecutor;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Text.RegularExpressions;
namespace AndroidUSBSocket
{
public class SocketClient
{
public const string LOCAL_PORT = "12580";
public SocketClient(string adb_path, string remote_port)
{
AdbExecutor adb = AdbExecutor.GetInstance(adb_path);
adb.Forward(LOCAL_PORT, remote_port);
}
public string Request(string msg)
{
Socket client = null;
try
{
client = create();
connect(client, LOCAL_PORT);
if (client.Connected)
{
send(client, msg);
return receive(client);
}
else
{
return "连接失败!";
}
}
catch(Exception e)
{
return $"Error:{e.Message}";
}
finally
{
client.Shutdown(SocketShutdown.Both);
client?.Close();
Request(msg);
}
}
private static void connect(Socket socket,string port)
{
IPAddress myIP = IPAddress.Parse("127.0.0.1");
IPEndPoint EPhost = new IPEndPoint(myIP, int.Parse(port));
socket.Connect(EPhost); //create connection
}
private static Socket create()
{
return new Socket(
AddressFamily.InterNetwork,
SocketType.Stream,
ProtocolType.Tcp);
}
private static void send(Socket socket, string msg)
{
//request
msg = msg.Replace("\n", "\\&"); //replace all '\n' to '\&', those will be replace to '\n' when server received this msg
msg += "\n"; //server is using readLine(), if not send a '\n' the stream won't push data to server
byte[] data = Encoding.UTF8.GetBytes(msg);
socket.Send(data); //send message to server
//socket.Shutdown(SocketShutdown.Send); //N-E-V-E-R close output stream, the socket will be closed together
Debug.WriteLine($"发送完毕(长度[{msg.Length}] 字节[{data.Length}]):\n{msg}");
}
private static string receive(Socket socket)
{
//get response
string str = "";
byte[] data = new byte[10240];
int len = 0;
int i = 0;
while ((i = socket.Receive(data)) != 0) //read response string
{
len += i;
string piece = Encoding.UTF8.GetString(data, 0, i);
str += piece;
}
Debug.WriteLine($"接收完毕(长度[{str.Length}] 字节[{len}]):\n{str}");
return str;
}
}
}
使用ADB进行端口的映射转发:adb forward tcp:local_port tcp:remote_port
SocketClient构造中的ADBExecutor就是用来执行这个命令的
另外有一点不明白的是 SocketClient的receive方法中,byte[]的size我定的是10240
因为如果定小了,在获取字符串的过程中就会因为这个尺寸不合适导致在边界上的字符变成???
C#不是很熟悉,这个地方不知道该怎么做,索性把size定得大一点,一般用不了这么长的字节数组
使用这个方法要注意的是,只能通过PC主动向Android端发起请求,看了很多文档,貌似Android端是不能主动请求PC的,这个好像跟ADB的机制有关
但是ADB我并不是理解得特别清楚,所以如果有大神知道如何让Android端主动请求PC端的服务器的话,希望不吝赐教!
有一个帖子说,Android通过USB连接电脑后,默认电脑的IP就是10.0.2.2,我试了一下,没啥成果,如果有人成功请联系我。
其他需要注意的地方在代码中的注释我都清楚地写出来了,欢迎交流。
/**
* Created by Jack Stone on 2016/11/17.
* Socket服务器,PC可以通过USB连接、ADB端口映射连接本服务器,不需要通过Wifi和网络
*/
public class TCPConnect implements Runnable {
private static final String TAG = "TCPConnect";
private final int SERVER_PORT = 10086;
private ServerSocket mServerSocket;
private Socket mClient;
private Callback callback;
public TCPConnect(Callback callback) {
this.callback = callback;
}
@Override
public void run() {
try {
String ip = InetAddress.getLocalHost().getHostAddress();
mServerSocket = new ServerSocket(SERVER_PORT);
callback.call("建立服务器:[" + ip + ":" + SERVER_PORT + "]");
} catch (IOException e) {
callback.call("建立服务器异常:" + e.getMessage());
}
while (true) {
BufferedOutputStream out = null;
BufferedReader in = null;
try {
mClient = mServerSocket.accept();
callback.call("建立链接:" + mClient.getInetAddress().toString() + ":" + mClient.getPort());
out = new BufferedOutputStream(mClient.getOutputStream());
in = new BufferedReader(new InputStreamReader(mClient.getInputStream()));
String request = receive(in);
callback.call("client:"+request);
send(out, request);
} catch (IOException e) {
Log.e(TAG, "run: ", e);
callback.call(e.getMessage());
} finally {
close(out);
close(in);
close(mClient);
}
}
}
private void send(OutputStream out, String msg) throws IOException {
msg += "\n";
out.write(msg.getBytes("utf-8"));
}
private String receive(BufferedReader in) throws IOException {
String r = in.readLine();
callback.call("origin request:"+r);
if(r.contains("\\&")) {
callback.call("进行\\&替换!");
r = r.replaceAll("\\\\&","\n");
}
return r;
}
private void close(OutputStream out) {
if (out != null) {
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
private void close(BufferedReader in) {
if (in != null) {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
private void close(Socket socket) {
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
Log.e(TAG, "run: ", e);
}
}
}
public interface Callback {
void call(String msg);
}
}
PC客户端
using CMDExecutor;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Text.RegularExpressions;
namespace AndroidUSBSocket
{
public class SocketClient
{
public const string LOCAL_PORT = "12580";
public SocketClient(string adb_path, string remote_port)
{
AdbExecutor adb = AdbExecutor.GetInstance(adb_path);
adb.Forward(LOCAL_PORT, remote_port);
}
public string Request(string msg)
{
Socket client = null;
try
{
client = create();
connect(client, LOCAL_PORT);
if (client.Connected)
{
send(client, msg);
return receive(client);
}
else
{
return "连接失败!";
}
}
catch(Exception e)
{
return $"Error:{e.Message}";
}
finally
{
client.Shutdown(SocketShutdown.Both);
client?.Close();
Request(msg);
}
}
private static void connect(Socket socket,string port)
{
IPAddress myIP = IPAddress.Parse("127.0.0.1");
IPEndPoint EPhost = new IPEndPoint(myIP, int.Parse(port));
socket.Connect(EPhost); //create connection
}
private static Socket create()
{
return new Socket(
AddressFamily.InterNetwork,
SocketType.Stream,
ProtocolType.Tcp);
}
private static void send(Socket socket, string msg)
{
//request
msg = msg.Replace("\n", "\\&"); //replace all '\n' to '\&', those will be replace to '\n' when server received this msg
msg += "\n"; //server is using readLine(), if not send a '\n' the stream won't push data to server
byte[] data = Encoding.UTF8.GetBytes(msg);
socket.Send(data); //send message to server
//socket.Shutdown(SocketShutdown.Send); //N-E-V-E-R close output stream, the socket will be closed together
Debug.WriteLine($"发送完毕(长度[{msg.Length}] 字节[{data.Length}]):\n{msg}");
}
private static string receive(Socket socket)
{
//get response
string str = "";
byte[] data = new byte[10240];
int len = 0;
int i = 0;
while ((i = socket.Receive(data)) != 0) //read response string
{
len += i;
string piece = Encoding.UTF8.GetString(data, 0, i);
str += piece;
}
Debug.WriteLine($"接收完毕(长度[{str.Length}] 字节[{len}]):\n{str}");
return str;
}
}
}
使用ADB进行端口的映射转发:adb forward tcp:local_port tcp:remote_port
SocketClient构造中的ADBExecutor就是用来执行这个命令的
另外有一点不明白的是 SocketClient的receive方法中,byte[]的size我定的是10240
因为如果定小了,在获取字符串的过程中就会因为这个尺寸不合适导致在边界上的字符变成???
C#不是很熟悉,这个地方不知道该怎么做,索性把size定得大一点,一般用不了这么长的字节数组
使用这个方法要注意的是,只能通过PC主动向Android端发起请求,看了很多文档,貌似Android端是不能主动请求PC的,这个好像跟ADB的机制有关
但是ADB我并不是理解得特别清楚,所以如果有大神知道如何让Android端主动请求PC端的服务器的话,希望不吝赐教!
有一个帖子说,Android通过USB连接电脑后,默认电脑的IP就是10.0.2.2,我试了一下,没啥成果,如果有人成功请联系我。
其他需要注意的地方在代码中的注释我都清楚地写出来了,欢迎交流。
相关文章推荐
- Ubuntu下Android手机通过USB连接PC方法
- Ubuntu下Android手机通过USB连接PC方法
- android pc通过wifi调试手机(无需USB连接)
- 【网络通信】Wince 和 PC 通过USB 用Socket 进行通信
- 如何防止手机通过USB连接PC充电时的关机闹钟异常现象?
- PC与Android设备通过USB建立通信连接
- PPC、PDA通过USB连接PC电脑上网
- 【网络通信】Wince 和 PC 通过USB 用Socket 进行通信
- Android作为服务器通过USB使用Socket协议向PC客户端发送文件
- PC通过USB连接高通平台
- android端和pc端使用usb进行socket通信,其中android是服务器端,pc是客户端。如何实现安卓端输入的数据通过按钮发送到pc端?
- Ubuntu下Android如何将手机通过USB连接PC开发测试
- PC端通过USB连接手机,检测手机端是否安装某个应用程序
- Android通过socket连接服务器(PC)
- Android与PC的Socket(TCP/IP)通信(by USB) 拒绝连接的
- PC客户端与Android服务端的Socket同步通信(USB)
- Socket中如何设置连接超时-通过测试(VC)
- Android通过Socket(TCP/IP)与PC通讯
- Android通过Socket(TCP/IP)与PC通讯
- Android 手机应用开发经验 之 通过Socket(TCP/IP)与PC通讯