侧边栏壁纸
博主头像
最闪啊姚凌武!博主等级

天下武功,唯快不破

  • 累计撰写 293 篇文章
  • 累计创建 34 个标签
  • 累计收到 10 条评论

目 录CONTENT

文章目录

PC客户端与Android服务端的Socket同步通信(USB)

姚凌武
2015-11-09 / 0 评论 / 0 点赞 / 8 阅读 / 115690 字

PC客户端与Android服务端的Socket同步通信(USB) 收藏

需求:

  1. 一个android端的service后台运行的程序,作为socket的服务器端;用于接收Pc client端发来的命令,来处理数据后,把结果发给PC client

2.PC端程序,作为socket的客户端,用于给android手机端发操作命令

难点分析:

  1. 手机一定要有adb模式,即插上USB线时马上提示的对话框选adb。好多对手机的操作都可以用adb直接作。

不过,我发现LG GW880就没有,要去下载个

2.android默认手机端的IP为“127.0.0.1”

  1. 要想联通PC与android手机的sokcet,一定要用adb forward 来作下端口转发才能连上socket.

view plaincopy to clipboardprint?

Runtime.getRuntime().exec("adb forward tcp:12580 tcp:10086");

Thread.sleep(3000);

Runtime.getRuntime().exec("adb forward tcp:12580 tcp:10086");

Thread.sleep(3000);

4.android端的service程序Install到手机上容易,但是还要有方法来从PC的client端来启动手机上的service ,这个办法可以通过PC端adb命令来发一个Broastcast ,手机端再写个接收BroastcastReceive来接收这个Broastcast,在这个BroastcastReceive来启动service

pc端命令:

view plaincopy to clipboardprint?

Runtime.getRuntime().exec(

"adb shell am broadcast -a NotifyServiceStart");

Runtime.getRuntime().exec(

"adb shell am broadcast -a NotifyServiceStart");

android端的代码:ServiceBroadcastReceiver.java

view plaincopy to clipboardprint?

package com.otheri.service;

import android.content.BroadcastReceiver;

import android.content.Context;

import android.content.Intent;

import android.util.Log;

public class ServiceBroadcastReceiver extends BroadcastReceiver {

private static String START_ACTION = "NotifyServiceStart";

private static String STOP_ACTION = "NotifyServiceStop";

@Override

public void onReceive(Context context, Intent intent) {

Log.d(androidService.TAG, Thread.currentThread().getName() + "---->"

+ "ServiceBroadcastReceiver onReceive");

String action = intent.getAction();

if (START_ACTION.equalsIgnoreCase(action)) {

context.startService(new Intent(context, androidService.class));

Log.d(androidService.TAG, Thread.currentThread().getName() + "---->"

+ "ServiceBroadcastReceiver onReceive start end");

} else if (STOP_ACTION.equalsIgnoreCase(action)) {

context.stopService(new Intent(context, androidService.class));

Log.d(androidService.TAG, Thread.currentThread().getName() + "---->"

+ "ServiceBroadcastReceiver onReceive stop end");

}

}

}

package com.otheri.service;

import android.content.BroadcastReceiver;

import android.content.Context;

import android.content.Intent;

import android.util.Log;

public class ServiceBroadcastReceiver extends BroadcastReceiver {

private static String START_ACTION = "NotifyServiceStart";

private static String STOP_ACTION = "NotifyServiceStop";

@Override

public void onReceive(Context context, Intent intent) {

Log.d(androidService.TAG, Thread.currentThread().getName() + "---->"

+ "ServiceBroadcastReceiver onReceive");

String action = intent.getAction();

if (START_ACTION.equalsIgnoreCase(action)) {

context.startService(new Intent(context, androidService.class));

Log.d(androidService.TAG, Thread.currentThread().getName() + "---->"

+ "ServiceBroadcastReceiver onReceive start end");

} else if (STOP_ACTION.equalsIgnoreCase(action)) {

context.stopService(new Intent(context, androidService.class));

Log.d(androidService.TAG, Thread.currentThread().getName() + "---->"

+ "ServiceBroadcastReceiver onReceive stop end");

}

}

}

  1. 由于是USB连接,所以socket就可以设计为一但连接就一直联通,即在new socket和开完out,in流后,就用个while(true){}来循环PC端和android端的读和写

android的代码:

view plaincopy to clipboardprint?

public void run() {

Log.d(androidService.TAG, Thread.currentThread().getName() + "---->"

+ "a client has connected to server!");

BufferedOutputStream out;

BufferedInputStream in;

try {

/* PC端发来的数据msg */

String currCMD = "";

out = new BufferedOutputStream(client.getOutputStream());

in = new BufferedInputStream(client.getInputStream());

// testSocket();// 测试socket方法

androidService.ioThreadFlag = true;

while (androidService.ioThreadFlag) {

try {

if (!client.isConnected()) {

break;

}

/* 接收PC发来的数据 */

Log.v(androidService.TAG, Thread.currentThread().getName()

+ "---->" + "will read......");

/* 读操作命令 */

currCMD = readCMDFromSocket(in);

Log.v(androidService.TAG, Thread.currentThread().getName()

+ "---->" + "**currCMD ==== " + currCMD);

/* 根据命令分别处理数据 */

if (currCMD.equals("1")) {

out.write("OK".getBytes());

out.flush();

} else if (currCMD.equals("2")) {

out.write("OK".getBytes());

out.flush();

} else if (currCMD.equals("3")) {

out.write("OK".getBytes());

out.flush();

} else if (currCMD.equals("4")) {

/* 准备接收文件数据 */

try {

out.write("service receive OK".getBytes());

out.flush();

} catch (IOException e) {

e.printStackTrace();

}

/* 接收文件数据,4字节文件长度,4字节文件格式,其后是文件数据 */

byte[] filelength = new byte[4];

byte[] fileformat = new byte[4];

byte[] filebytes = null;

/* 从socket流中读取完整文件数据 */

filebytes = receiveFileFromSocket(in, out, filelength,

fileformat);

// Log.v(Service139.TAG, "receive data =" + new

// String(filebytes));

try {

/* 生成文件 */

File file = FileHelper.newFile("R0013340.JPG");

FileHelper.writeFile(file, filebytes, 0,

filebytes.length);

} catch (IOException e) {

e.printStackTrace();

}

} else if (currCMD.equals("exit")) {

}

} catch (Exception e) {

// try {

// out.write("error".getBytes("utf-8"));

// out.flush();

// } catch (IOException e1) {

// e1.printStackTrace();

// }

Log.e(androidService.TAG, Thread.currentThread().getName()

+ "---->" + "read write error111111");

}

}

out.close();

in.close();

} catch (Exception e) {

Log.e(androidService.TAG, Thread.currentThread().getName()

+ "---->" + "read write error222222");

e.printStackTrace();

} finally {

try {

if (client != null) {

Log.v(androidService.TAG, Thread.currentThread().getName()

+ "---->" + "client.close()");

client.close();

}

} catch (IOException e) {

Log.e(androidService.TAG, Thread.currentThread().getName()

+ "---->" + "read write error333333");

e.printStackTrace();

}

}

public void run() {

Log.d(androidService.TAG, Thread.currentThread().getName() + "---->"

+ "a client has connected to server!");

BufferedOutputStream out;

BufferedInputStream in;

try {

/* PC端发来的数据msg */

String currCMD = "";

out = new BufferedOutputStream(client.getOutputStream());

in = new BufferedInputStream(client.getInputStream());

// testSocket();// 测试socket方法

androidService.ioThreadFlag = true;

while (androidService.ioThreadFlag) {

try {

if (!client.isConnected()) {

break;

}

/* 接收PC发来的数据 */

Log.v(androidService.TAG, Thread.currentThread().getName()

+ "---->" + "will read......");

/* 读操作命令 */

currCMD = readCMDFromSocket(in);

Log.v(androidService.TAG, Thread.currentThread().getName()

+ "---->" + "**currCMD ==== " + currCMD);

/* 根据命令分别处理数据 */

if (currCMD.equals("1")) {

out.write("OK".getBytes());

out.flush();

} else if (currCMD.equals("2")) {

out.write("OK".getBytes());

out.flush();

} else if (currCMD.equals("3")) {

out.write("OK".getBytes());

out.flush();

} else if (currCMD.equals("4")) {

/* 准备接收文件数据 */

try {

out.write("service receive OK".getBytes());

out.flush();

} catch (IOException e) {

e.printStackTrace();

}

/* 接收文件数据,4字节文件长度,4字节文件格式,其后是文件数据 */

byte[] filelength = new byte[4];

byte[] fileformat = new byte[4];

byte[] filebytes = null;

/* 从socket流中读取完整文件数据 */

filebytes = receiveFileFromSocket(in, out, filelength,

fileformat);

// Log.v(Service139.TAG, "receive data =" + new

// String(filebytes));

try {

/* 生成文件 */

File file = FileHelper.newFile("R0013340.JPG");

FileHelper.writeFile(file, filebytes, 0,

filebytes.length);

} catch (IOException e) {

e.printStackTrace();

}

} else if (currCMD.equals("exit")) {

}

} catch (Exception e) {

// try {

// out.write("error".getBytes("utf-8"));

// out.flush();

// } catch (IOException e1) {

// e1.printStackTrace();

// }

Log.e(androidService.TAG, Thread.currentThread().getName()

+ "---->" + "read write error111111");

}

}

out.close();

in.close();

} catch (Exception e) {

Log.e(androidService.TAG, Thread.currentThread().getName()

+ "---->" + "read write error222222");

e.printStackTrace();

} finally {

try {

if (client != null) {

Log.v(androidService.TAG, Thread.currentThread().getName()

+ "---->" + "client.close()");

client.close();

}

} catch (IOException e) {

Log.e(androidService.TAG, Thread.currentThread().getName()

+ "---->" + "read write error333333");

e.printStackTrace();

}

}

  1. 如果是在PC端和android端的读写操作来while(true){}循环,这样socket流的结尾不好判断,不能用“-1”来判断,因为“-1”是只有在socket关闭时才作为判断结尾。

7.socket在out.write(bytes);时,要是数据太大时,超过socket的缓存,socket自动分包发送,所以对方就一定要用循环来多次读。最好的办法就是服务器和客户端协议好,比如发文件时,先写过来一个要发送的文件的大小,然后再发送文件;对方用这个大小,来循环读取数据。

android端接收数据的代码:

view plaincopy to clipboardprint?

/**

* 功能:从socket流中读取完整文件数据

*

* InputStream in:socket输入流

*

* byte[] filelength: 流的前4个字节存储要转送的文件的字节数

*

* byte[] fileformat:流的前5-8字节存储要转送的文件的格式(如.apk)

*

* */

public static byte[] receiveFileFromSocket(InputStream in,

OutputStream out, byte[] filelength, byte[] fileformat) {

byte[] filebytes = null;// 文件数据

try {

int filelen = MyUtil.bytesToInt(filelength);// 文件长度从4字节byte[]转成Int

String strtmp = "read file length ok:" + filelen;

out.write(strtmp.getBytes("utf-8"));

out.flush();

filebytes = new byte[filelen];

int pos = 0;

int rcvLen = 0;

while ((rcvLen = in.read(filebytes, pos, filelen - pos)) > 0) {

pos += rcvLen;

}

Log.v(androidService.TAG, Thread.currentThread().getName()

+ "---->" + "read file OK:file size=" + filebytes.length);

out.write("read file ok".getBytes("utf-8"));

out.flush();

} catch (Exception e) {

Log.v(androidService.TAG, Thread.currentThread().getName()

+ "---->" + "receiveFileFromSocket error");

e.printStackTrace();

}

return filebytes;

}

/**

* 功能:从socket流中读取完整文件数据

*

* InputStream in:socket输入流

*

* byte[] filelength: 流的前4个字节存储要转送的文件的字节数

*

* byte[] fileformat:流的前5-8字节存储要转送的文件的格式(如.apk)

*

* */

public static byte[] receiveFileFromSocket(InputStream in,

OutputStream out, byte[] filelength, byte[] fileformat) {

byte[] filebytes = null;// 文件数据

try {

int filelen = MyUtil.bytesToInt(filelength);// 文件长度从4字节byte[]转成Int

String strtmp = "read file length ok:" + filelen;

out.write(strtmp.getBytes("utf-8"));

out.flush();

filebytes = new byte[filelen];

int pos = 0;

int rcvLen = 0;

while ((rcvLen = in.read(filebytes, pos, filelen - pos)) > 0) {

pos += rcvLen;

}

Log.v(androidService.TAG, Thread.currentThread().getName()

+ "---->" + "read file OK:file size=" + filebytes.length);

out.write("read file ok".getBytes("utf-8"));

out.flush();

} catch (Exception e) {

Log.v(androidService.TAG, Thread.currentThread().getName()

+ "---->" + "receiveFileFromSocket error");

e.printStackTrace();

}

return filebytes;

}

8.socket的最重要的机制就是读写采用的是阻塞的方式,如果客户端作为命令发起者,服务器端作为接收者的话,只有当客户端client用out.writer()写到输出流里后,即流中有数据service的read才会执行,不然就会一直停在read()那里等数据。

  1. 还要让服务器端可以同时连接多个client,即服务器端用new thread()来作数据读取操作。

源码:

客户端(pc端):

testPcClient.java

view plaincopy to clipboardprint?

import java.io.BufferedInputStream;

import java.io.BufferedOutputStream;

import java.io.BufferedReader;

import java.io.ByteArrayOutputStream;

import java.io.IOException;

import java.io.InputStream;

import java.io.InputStreamReader;

import java.net.InetAddress;

import java.net.Socket;

import java.net.UnknownHostException;

public class testPcClient {

/**

* @param args

* @throws InterruptedException

*/

public static void main(String[] args) throws InterruptedException {

try {

Runtime.getRuntime().exec(

"adb shell am broadcast -a NotifyServiceStop");

Thread.sleep(3000);

Runtime.getRuntime().exec("adb forward tcp:12580 tcp:10086");

Thread.sleep(3000);

Runtime.getRuntime().exec(

"adb shell am broadcast -a NotifyServiceStart");

Thread.sleep(3000);

} catch (IOException e3) {

e3.printStackTrace();

}

Socket socket = null;

try {

InetAddress serverAddr = null;

serverAddr = InetAddress.getByName("127.0.0.1");

System.out.println("TCP 1111" + "C: Connecting...");

socket = new Socket(serverAddr, 12580);

String str = "hi,wufenglong";

System.out.println("TCP 221122" + "C:RECEIVE");

BufferedOutputStream out = new BufferedOutputStream(socket

.getOutputStream());

BufferedInputStream in = new BufferedInputStream(socket

.getInputStream());

BufferedReader br = new BufferedReader(new InputStreamReader(

System.in));

boolean flag = true;

while (flag) {

System.out.print("请输入1~6的数字,退出输入exit:");

String strWord = br.readLine();// 从控制台输入1~6

if (strWord.equals("1")) {

out.write("1".getBytes());

out.flush();

System.out.println("1 finish sending the data");

String strFormsocket = readFromSocket(in);

System.out.println("the data sent by server is:\r\n"

+ strFormsocket);

System.out

.println("=============================================");

} else if (strWord.equals("2")) {

out.write("2".getBytes());

out.flush();

System.out.println("2 finish sending the data");

String strFormsocket = readFromSocket(in);

System.out.println("the data sent by server is:\r\n"

+ strFormsocket);

System.out

.println("=============================================");

} else if (strWord.equals("3")) {

out.write("3".getBytes());

out.flush();

System.out.println("3 finish sending the data");

String strFormsocket = readFromSocket(in);

System.out.println("the data sent by server is:\r\n"

+ strFormsocket);

System.out

.println("=============================================");

} else if (strWord.equals("4")) {

/* 发送命令 */

out.write("4".getBytes());

out.flush();

System.out.println("send file finish sending the CMD:");

/* 服务器反馈:准备接收 */

String strFormsocket = readFromSocket(in);

System.out

.println("service ready receice data:UPDATE_CONTACTS:"

+ strFormsocket);

byte[] filebytes = FileHelper.readFile("R0013340.JPG");

System.out.println("file size=" + filebytes.length);

/* 将整数转成4字节byte数组 */

byte[] filelength = new byte[4];

filelength = tools.intToByte(filebytes.length);

/* 将.apk字符串转成4字节byte数组 */

byte[] fileformat = null;

fileformat = ".apk".getBytes();

System.out

.println("fileformat length=" + fileformat.length);

/* 字节流中前4字节为文件长度,4字节文件格式,以后是文件流 */

/* 注意如果write里的byte[]超过socket的缓存,系统自动分包写过去,所以对方要循环写完 */

out.write(filelength);

out.flush();

String strok1 = readFromSocket(in);

System.out.println("service receive filelength :" + strok1);

// out.write(fileformat);

// out.flush();

// String strok2 = readFromSocket(in);

// System.out.println("service receive fileformat :" +

// strok2);

System.out.println("write data to android");

out.write(filebytes);

out.flush();

System.out.println("*********");

/* 服务器反馈:接收成功 */

String strread = readFromSocket(in);

System.out.println(" send data success:" + strread);

System.out

.println("=============================================");

} else if (strWord.equalsIgnoreCase("EXIT")) {

out.write("EXIT".getBytes());

out.flush();

System.out.println("EXIT finish sending the data");

String strFormsocket = readFromSocket(in);

System.out.println("the data sent by server is:\r\n"

+ strFormsocket);

flag = false;

System.out

.println("=============================================");

}

}

} catch (UnknownHostException e1) {

System.out.println("TCP 331133" + "ERROR:" + e1.toString());

} catch (Exception e2) {

System.out.println("TCP 441144" + "ERROR:" + e2.toString());

} finally {

try {

if (socket != null) {

socket.close();

System.out.println("socket.close()");

}

} catch (IOException e) {

System.out.println("TCP 5555" + "ERROR:" + e.toString());

}

}

}

/* 从InputStream流中读数据 */

public static String readFromSocket(InputStream in) {

int MAX_BUFFER_BYTES = 4000;

String msg = "";

byte[] tempbuffer = new byte[MAX_BUFFER_BYTES];

try {

int numReadedBytes = in.read(tempbuffer, 0, tempbuffer.length);

msg = new String(tempbuffer, 0, numReadedBytes, "utf-8");

tempbuffer = null;

} catch (Exception e) {

e.printStackTrace();

}

// Log.v(Service139.TAG, "msg=" + msg);

return msg;

}

}

import java.io.BufferedInputStream;

import java.io.BufferedOutputStream;

import java.io.BufferedReader;

import java.io.ByteArrayOutputStream;

import java.io.IOException;

import java.io.InputStream;

import java.io.InputStreamReader;

import java.net.InetAddress;

import java.net.Socket;

import java.net.UnknownHostException;

public class testPcClient {

/**

* @param args

* @throws InterruptedException

*/

public static void main(String[] args) throws InterruptedException {

try {

Runtime.getRuntime().exec(

"adb shell am broadcast -a NotifyServiceStop");

Thread.sleep(3000);

Runtime.getRuntime().exec("adb forward tcp:12580 tcp:10086");

Thread.sleep(3000);

Runtime.getRuntime().exec(

"adb shell am broadcast -a NotifyServiceStart");

Thread.sleep(3000);

} catch (IOException e3) {

e3.printStackTrace();

}

Socket socket = null;

try {

InetAddress serverAddr = null;

serverAddr = InetAddress.getByName("127.0.0.1");

System.out.println("TCP 1111" + "C: Connecting...");

socket = new Socket(serverAddr, 12580);

String str = "hi,wufenglong";

System.out.println("TCP 221122" + "C:RECEIVE");

BufferedOutputStream out = new BufferedOutputStream(socket

.getOutputStream());

BufferedInputStream in = new BufferedInputStream(socket

.getInputStream());

BufferedReader br = new BufferedReader(new InputStreamReader(

System.in));

boolean flag = true;

while (flag) {

System.out.print("请输入1~6的数字,退出输入exit:");

String strWord = br.readLine();// 从控制台输入1~6

if (strWord.equals("1")) {

out.write("1".getBytes());

out.flush();

System.out.println("1 finish sending the data");

String strFormsocket = readFromSocket(in);

System.out.println("the data sent by server is:\r\n"

+ strFormsocket);

System.out

.println("=============================================");

} else if (strWord.equals("2")) {

out.write("2".getBytes());

out.flush();

System.out.println("2 finish sending the data");

String strFormsocket = readFromSocket(in);

System.out.println("the data sent by server is:\r\n"

+ strFormsocket);

System.out

.println("=============================================");

} else if (strWord.equals("3")) {

out.write("3".getBytes());

out.flush();

System.out.println("3 finish sending the data");

String strFormsocket = readFromSocket(in);

System.out.println("the data sent by server is:\r\n"

+ strFormsocket);

System.out

.println("=============================================");

} else if (strWord.equals("4")) {

/* 发送命令 */

out.write("4".getBytes());

out.flush();

System.out.println("send file finish sending the CMD:");

/* 服务器反馈:准备接收 */

String strFormsocket = readFromSocket(in);

System.out

.println("service ready receice data:UPDATE_CONTACTS:"

+ strFormsocket);

byte[] filebytes = FileHelper.readFile("R0013340.JPG");

System.out.println("file size=" + filebytes.length);

/* 将整数转成4字节byte数组 */

byte[] filelength = new byte[4];

filelength = tools.intToByte(filebytes.length);

/* 将.apk字符串转成4字节byte数组 */

byte[] fileformat = null;

fileformat = ".apk".getBytes();

System.out

.println("fileformat length=" + fileformat.length);

/* 字节流中前4字节为文件长度,4字节文件格式,以后是文件流 */

/* 注意如果write里的byte[]超过socket的缓存,系统自动分包写过去,所以对方要循环写完 */

out.write(filelength);

out.flush();

String strok1 = readFromSocket(in);

System.out.println("service receive filelength :" + strok1);

// out.write(fileformat);

// out.flush();

// String strok2 = readFromSocket(in);

// System.out.println("service receive fileformat :" +

// strok2);

System.out.println("write data to android");

out.write(filebytes);

out.flush();

System.out.println("*********");

/* 服务器反馈:接收成功 */

String strread = readFromSocket(in);

System.out.println(" send data success:" + strread);

System.out

.println("=============================================");

} else if (strWord.equalsIgnoreCase("EXIT")) {

out.write("EXIT".getBytes());

out.flush();

System.out.println("EXIT finish sending the data");

String strFormsocket = readFromSocket(in);

System.out.println("the data sent by server is:\r\n"

+ strFormsocket);

flag = false;

System.out

.println("=============================================");

}

}

} catch (UnknownHostException e1) {

System.out.println("TCP 331133" + "ERROR:" + e1.toString());

} catch (Exception e2) {

System.out.println("TCP 441144" + "ERROR:" + e2.toString());

} finally {

try {

if (socket != null) {

socket.close();

System.out.println("socket.close()");

}

} catch (IOException e) {

System.out.println("TCP 5555" + "ERROR:" + e.toString());

}

}

}

/* 从InputStream流中读数据 */

public static String readFromSocket(InputStream in) {

int MAX_BUFFER_BYTES = 4000;

String msg = "";

byte[] tempbuffer = new byte[MAX_BUFFER_BYTES];

try {

int numReadedBytes = in.read(tempbuffer, 0, tempbuffer.length);

msg = new String(tempbuffer, 0, numReadedBytes, "utf-8");

tempbuffer = null;

} catch (Exception e) {

e.printStackTrace();

}

// Log.v(Service139.TAG, "msg=" + msg);

return msg;

}

}

android服务器端:

主类androidService.java

view plaincopy to clipboardprint?

package com.otheri.service;

import java.io.File;

import java.io.IOException;

import java.net.ServerSocket;

import java.net.Socket;

import android.app.Service;

import android.content.BroadcastReceiver;

import android.content.Context;

import android.content.Intent;

import android.content.IntentFilter;

import android.os.IBinder;

import android.util.Log;

/**

* 设置:android手机

*

*

* */

public class androidService extends Service {

public static final String TAG = "TAG";

public static Boolean mainThreadFlag = true;

public static Boolean ioThreadFlag = true;

ServerSocket serverSocket = null;

final int SERVER_PORT = 10086;

File testFile;

private sysBroadcastReceiver sysBR;

@Override

public void onCreate() {

super.onCreate();

Log.v(TAG, Thread.currentThread().getName() + "---->" + " onCreate");

/* 创建内部类sysBroadcastReceiver 并注册registerReceiver */

sysRegisterReceiver();

new Thread() {

public void run() {

doListen();

};

}.start();

}

private void doListen() {

Log.d(TAG, Thread.currentThread().getName() + "---->"

+ " doListen() START");

serverSocket = null;

try {

Log.d(TAG, Thread.currentThread().getName() + "---->"

+ " doListen() new serverSocket");

serverSocket = new ServerSocket(SERVER_PORT);

boolean mainThreadFlag = true;

while (mainThreadFlag) {

Log.d(TAG, Thread.currentThread().getName() + "---->"

+ " doListen() listen");

Socket client = serverSocket.accept();

new Thread(new ThreadReadWriterIOSocket(this, client)).start();

}

} catch (IOException e1) {

Log.v(androidService.TAG, Thread.currentThread().getName()

+ "---->" + "new serverSocket error");

e1.printStackTrace();

}

}

/* 创建内部类sysBroadcastReceiver 并注册registerReceiver */

private void sysRegisterReceiver() {

Log.v(TAG, Thread.currentThread().getName() + "---->"

+ "sysRegisterReceiver");

sysBR = new sysBroadcastReceiver();

/* 注册BroadcastReceiver */

IntentFilter filter1 = new IntentFilter();

/* 新的应用程序被安装到了设备上的广播 */

filter1.addAction("android.intent.action.PACKAGE_ADDED");

filter1.addDataScheme("package");

filter1.addAction("android.intent.action.PACKAGE_REMOVED");

filter1.addDataScheme("package");

registerReceiver(sysBR, filter1);

}

/* 内部类:BroadcastReceiver 用于接收系统事件 */

private class sysBroadcastReceiver extends BroadcastReceiver {

@Override

public void onReceive(Context context, Intent intent) {

String action = intent.getAction();

if (action.equalsIgnoreCase("android.intent.action.PACKAGE_ADDED")) {

// ReadInstalledAPP();

} else if (action

.equalsIgnoreCase("android.intent.action.PACKAGE_REMOVED")) {

// ReadInstalledAPP();

}

Log.v(TAG, Thread.currentThread().getName() + "---->"

+ "sysBroadcastReceiver onReceive");

}

}

@Override

public void onDestroy() {

super.onDestroy();

// 关闭线程

mainThreadFlag = false;

ioThreadFlag = false;

// 关闭服务器

try {

Log.v(TAG, Thread.currentThread().getName() + "---->"

+ "serverSocket.close()");

serverSocket.close();

} catch (IOException e) {

e.printStackTrace();

}

Log.v(TAG, Thread.currentThread().getName() + "---->"

+ "**************** onDestroy****************");

}

@Override

public void onStart(Intent intent, int startId) {

Log.d(TAG, Thread.currentThread().getName() + "---->" + " onStart()");

super.onStart(intent, startId);

}

@Override

public IBinder onBind(Intent arg0) {

Log.d(TAG, " onBind");

return null;

}

}

package com.otheri.service;

import java.io.File;

import java.io.IOException;

import java.net.ServerSocket;

import java.net.Socket;

import android.app.Service;

import android.content.BroadcastReceiver;

import android.content.Context;

import android.content.Intent;

import android.content.IntentFilter;

import android.os.IBinder;

import android.util.Log;

/**

* 设置:android手机

*

*

* */

public class androidService extends Service {

public static final String TAG = "TAG";

public static Boolean mainThreadFlag = true;

public static Boolean ioThreadFlag = true;

ServerSocket serverSocket = null;

final int SERVER_PORT = 10086;

File testFile;

private sysBroadcastReceiver sysBR;

@Override

public void onCreate() {

super.onCreate();

Log.v(TAG, Thread.currentThread().getName() + "---->" + " onCreate");

/* 创建内部类sysBroadcastReceiver 并注册registerReceiver */

sysRegisterReceiver();

new Thread() {

public void run() {

doListen();

};

}.start();

}

private void doListen() {

Log.d(TAG, Thread.currentThread().getName() + "---->"

+ " doListen() START");

serverSocket = null;

try {

Log.d(TAG, Thread.currentThread().getName() + "---->"

+ " doListen() new serverSocket");

serverSocket = new ServerSocket(SERVER_PORT);

boolean mainThreadFlag = true;

while (mainThreadFlag) {

Log.d(TAG, Thread.currentThread().getName() + "---->"

+ " doListen() listen");

Socket client = serverSocket.accept();

new Thread(new ThreadReadWriterIOSocket(this, client)).start();

}

} catch (IOException e1) {

Log.v(androidService.TAG, Thread.currentThread().getName()

+ "---->" + "new serverSocket error");

e1.printStackTrace();

}

}

/* 创建内部类sysBroadcastReceiver 并注册registerReceiver */

private void sysRegisterReceiver() {

Log.v(TAG, Thread.currentThread().getName() + "---->"

+ "sysRegisterReceiver");

sysBR = new sysBroadcastReceiver();

/* 注册BroadcastReceiver */

IntentFilter filter1 = new IntentFilter();

/* 新的应用程序被安装到了设备上的广播 */

filter1.addAction("android.intent.action.PACKAGE_ADDED");

filter1.addDataScheme("package");

filter1.addAction("android.intent.action.PACKAGE_REMOVED");

filter1.addDataScheme("package");

registerReceiver(sysBR, filter1);

}

/* 内部类:BroadcastReceiver 用于接收系统事件 */

private class sysBroadcastReceiver extends BroadcastReceiver {

@Override

public void onReceive(Context context, Intent intent) {

String action = intent.getAction();

if (action.equalsIgnoreCase("android.intent.action.PACKAGE_ADDED")) {

// ReadInstalledAPP();

} else if (action

.equalsIgnoreCase("android.intent.action.PACKAGE_REMOVED")) {

// ReadInstalledAPP();

}

Log.v(TAG, Thread.currentThread().getName() + "---->"

+ "sysBroadcastReceiver onReceive");

}

}

@Override

public void onDestroy() {

super.onDestroy();

// 关闭线程

mainThreadFlag = false;

ioThreadFlag = false;

// 关闭服务器

try {

Log.v(TAG, Thread.currentThread().getName() + "---->"

+ "serverSocket.close()");

serverSocket.close();

} catch (IOException e) {

e.printStackTrace();

}

Log.v(TAG, Thread.currentThread().getName() + "---->"

+ "**************** onDestroy****************");

}

@Override

public void onStart(Intent intent, int startId) {

Log.d(TAG, Thread.currentThread().getName() + "---->" + " onStart()");

super.onStart(intent, startId);

}

@Override

public IBinder onBind(Intent arg0) {

Log.d(TAG, " onBind");

return null;

}

}

用于接收PC发来的Broastcast并启动主类service的ServiceBroadcastReceiver.java

view plaincopy to clipboardprint?

package com.otheri.service;

import android.content.BroadcastReceiver;

import android.content.Context;

import android.content.Intent;

import android.util.Log;

public class ServiceBroadcastReceiver extends BroadcastReceiver {

private static String START_ACTION = "NotifyServiceStart";

private static String STOP_ACTION = "NotifyServiceStop";

@Override

public void onReceive(Context context, Intent intent) {

Log.d(androidService.TAG, Thread.currentThread().getName() + "---->"

+ "ServiceBroadcastReceiver onReceive");

String action = intent.getAction();

if (START_ACTION.equalsIgnoreCase(action)) {

context.startService(new Intent(context, androidService.class));

Log.d(androidService.TAG, Thread.currentThread().getName() + "---->"

+ "ServiceBroadcastReceiver onReceive start end");

} else if (STOP_ACTION.equalsIgnoreCase(action)) {

context.stopService(new Intent(context, androidService.class));

Log.d(androidService.TAG, Thread.currentThread().getName() + "---->"

+ "ServiceBroadcastReceiver onReceive stop end");

}

}

}

package com.otheri.service;

import android.content.BroadcastReceiver;

import android.content.Context;

import android.content.Intent;

import android.util.Log;

public class ServiceBroadcastReceiver extends BroadcastReceiver {

private static String START_ACTION = "NotifyServiceStart";

private static String STOP_ACTION = "NotifyServiceStop";

@Override

public void onReceive(Context context, Intent intent) {

Log.d(androidService.TAG, Thread.currentThread().getName() + "---->"

+ "ServiceBroadcastReceiver onReceive");

String action = intent.getAction();

if (START_ACTION.equalsIgnoreCase(action)) {

context.startService(new Intent(context, androidService.class));

Log.d(androidService.TAG, Thread.currentThread().getName() + "---->"

+ "ServiceBroadcastReceiver onReceive start end");

} else if (STOP_ACTION.equalsIgnoreCase(action)) {

context.stopService(new Intent(context, androidService.class));

Log.d(androidService.TAG, Thread.currentThread().getName() + "---->"

+ "ServiceBroadcastReceiver onReceive stop end");

}

}

}

用于新socket连接的读写线程类ThreadReadWriterIOSocket.java

view plaincopy to clipboardprint?

package com.otheri.service;

import java.io.BufferedInputStream;

import java.io.BufferedOutputStream;

import java.io.ByteArrayOutputStream;

import java.io.File;

import java.io.IOException;

import java.io.InputStream;

import java.io.OutputStream;

import java.net.Socket;

import android.content.Context;

import android.util.Log;

import com.otheri.util.FileHelper;

import com.otheri.util.MyUtil;

/**

* 功能:用于socket的交互

*

* @author wufenglong

*

*/

public class ThreadReadWriterIOSocket implements Runnable {

private Socket client;

private Context context;

ThreadReadWriterIOSocket(Context context, Socket client) {

this.client = client;

this.context = context;

}

@Override

public void run() {

Log.d(androidService.TAG, Thread.currentThread().getName() + "---->"

+ "a client has connected to server!");

BufferedOutputStream out;

BufferedInputStream in;

try {

/* PC端发来的数据msg */

String currCMD = "";

out = new BufferedOutputStream(client.getOutputStream());

in = new BufferedInputStream(client.getInputStream());

// testSocket();// 测试socket方法

androidService.ioThreadFlag = true;

while (androidService.ioThreadFlag) {

try {

if (!client.isConnected()) {

break;

}

/* 接收PC发来的数据 */

Log.v(androidService.TAG, Thread.currentThread().getName()

+ "---->" + "will read......");

/* 读操作命令 */

currCMD = readCMDFromSocket(in);

Log.v(androidService.TAG, Thread.currentThread().getName()

+ "---->" + "**currCMD ==== " + currCMD);

/* 根据命令分别处理数据 */

if (currCMD.equals("1")) {

out.write("OK".getBytes());

out.flush();

} else if (currCMD.equals("2")) {

out.write("OK".getBytes());

out.flush();

} else if (currCMD.equals("3")) {

out.write("OK".getBytes());

out.flush();

} else if (currCMD.equals("4")) {

/* 准备接收文件数据 */

try {

out.write("service receive OK".getBytes());

out.flush();

} catch (IOException e) {

e.printStackTrace();

}

/* 接收文件数据,4字节文件长度,4字节文件格式,其后是文件数据 */

byte[] filelength = new byte[4];

byte[] fileformat = new byte[4];

byte[] filebytes = null;

/* 从socket流中读取完整文件数据 */

filebytes = receiveFileFromSocket(in, out, filelength,

fileformat);

// Log.v(Service139.TAG, "receive data =" + new

// String(filebytes));

try {

/* 生成文件 */

File file = FileHelper.newFile("R0013340.JPG");

FileHelper.writeFile(file, filebytes, 0,

filebytes.length);

} catch (IOException e) {

e.printStackTrace();

}

} else if (currCMD.equals("exit")) {

}

} catch (Exception e) {

// try {

// out.write("error".getBytes("utf-8"));

// out.flush();

// } catch (IOException e1) {

// e1.printStackTrace();

// }

Log.e(androidService.TAG, Thread.currentThread().getName()

+ "---->" + "read write error111111");

}

}

out.close();

in.close();

} catch (Exception e) {

Log.e(androidService.TAG, Thread.currentThread().getName()

+ "---->" + "read write error222222");

e.printStackTrace();

} finally {

try {

if (client != null) {

Log.v(androidService.TAG, Thread.currentThread().getName()

+ "---->" + "client.close()");

client.close();

}

} catch (IOException e) {

Log.e(androidService.TAG, Thread.currentThread().getName()

+ "---->" + "read write error333333");

e.printStackTrace();

}

}

}

/**

* 功能:从socket流中读取完整文件数据

*

* InputStream in:socket输入流

*

* byte[] filelength: 流的前4个字节存储要转送的文件的字节数

*

* byte[] fileformat:流的前5-8字节存储要转送的文件的格式(如.apk)

*

* */

public static byte[] receiveFileFromSocket(InputStream in,

OutputStream out, byte[] filelength, byte[] fileformat) {

byte[] filebytes = null;// 文件数据

try {

in.read(filelength);// 读文件长度

int filelen = MyUtil.bytesToInt(filelength);// 文件长度从4字节byte[]转成Int

String strtmp = "read file length ok:" + filelen;

out.write(strtmp.getBytes("utf-8"));

out.flush();

filebytes = new byte[filelen];

int pos = 0;

int rcvLen = 0;

while ((rcvLen = in.read(filebytes, pos, filelen - pos)) > 0) {

pos += rcvLen;

}

Log.v(androidService.TAG, Thread.currentThread().getName()

+ "---->" + "read file OK:file size=" + filebytes.length);

out.write("read file ok".getBytes("utf-8"));

out.flush();

} catch (Exception e) {

Log.v(androidService.TAG, Thread.currentThread().getName()

+ "---->" + "receiveFileFromSocket error");

e.printStackTrace();

}

return filebytes;

}

/* 读取命令 */

public static String readCMDFromSocket(InputStream in) {

int MAX_BUFFER_BYTES = 2048;

String msg = "";

byte[] tempbuffer = new byte[MAX_BUFFER_BYTES];

try {

int numReadedBytes = in.read(tempbuffer, 0, tempbuffer.length);

msg = new String(tempbuffer, 0, numReadedBytes, "utf-8");

tempbuffer = null;

} catch (Exception e) {

Log.v(androidService.TAG, Thread.currentThread().getName()

+ "---->" + "readFromSocket error");

e.printStackTrace();

}

// Log.v(Service139.TAG, "msg=" + msg);

return msg;

}

}

package com.otheri.service;

import java.io.BufferedInputStream;

import java.io.BufferedOutputStream;

import java.io.ByteArrayOutputStream;

import java.io.File;

import java.io.IOException;

import java.io.InputStream;

import java.io.OutputStream;

import java.net.Socket;

import android.content.Context;

import android.util.Log;

import com.otheri.util.FileHelper;

import com.otheri.util.MyUtil;

/**

* 功能:用于socket的交互

*

* @author wufenglong

*

*/

public class ThreadReadWriterIOSocket implements Runnable {

private Socket client;

private Context context;

ThreadReadWriterIOSocket(Context context, Socket client) {

this.client = client;

this.context = context;

}

@Override

public void run() {

Log.d(androidService.TAG, Thread.currentThread().getName() + "---->"

+ "a client has connected to server!");

BufferedOutputStream out;

BufferedInputStream in;

try {

/* PC端发来的数据msg */

String currCMD = "";

out = new BufferedOutputStream(client.getOutputStream());

in = new BufferedInputStream(client.getInputStream());

// testSocket();// 测试socket方法

androidService.ioThreadFlag = true;

while (androidService.ioThreadFlag) {

try {

if (!client.isConnected()) {

break;

}

/* 接收PC发来的数据 */

Log.v(androidService.TAG, Thread.currentThread().getName()

+ "---->" + "will read......");

/* 读操作命令 */

currCMD = readCMDFromSocket(in);

Log.v(androidService.TAG, Thread.currentThread().getName()

+ "---->" + "**currCMD ==== " + currCMD);

/* 根据命令分别处理数据 */

if (currCMD.equals("1")) {

out.write("OK".getBytes());

out.flush();

} else if (currCMD.equals("2")) {

out.write("OK".getBytes());

out.flush();

} else if (currCMD.equals("3")) {

out.write("OK".getBytes());

out.flush();

} else if (currCMD.equals("4")) {

/* 准备接收文件数据 */

try {

out.write("service receive OK".getBytes());

out.flush();

} catch (IOException e) {

e.printStackTrace();

}

/* 接收文件数据,4字节文件长度,4字节文件格式,其后是文件数据 */

byte[] filelength = new byte[4];

byte[] fileformat = new byte[4];

byte[] filebytes = null;

/* 从socket流中读取完整文件数据 */

filebytes = receiveFileFromSocket(in, out, filelength,

fileformat);

// Log.v(Service139.TAG, "receive data =" + new

// String(filebytes));

try {

/* 生成文件 */

File file = FileHelper.newFile("R0013340.JPG");

FileHelper.writeFile(file, filebytes, 0,

filebytes.length);

} catch (IOException e) {

e.printStackTrace();

}

} else if (currCMD.equals("exit")) {

}

} catch (Exception e) {

// try {

// out.write("error".getBytes("utf-8"));

// out.flush();

// } catch (IOException e1) {

// e1.printStackTrace();

// }

Log.e(androidService.TAG, Thread.currentThread().getName()

+ "---->" + "read write error111111");

}

}

out.close();

in.close();

} catch (Exception e) {

Log.e(androidService.TAG, Thread.currentThread().getName()

+ "---->" + "read write error222222");

e.printStackTrace();

} finally {

try {

if (client != null) {

Log.v(androidService.TAG, Thread.currentThread().getName()

+ "---->" + "client.close()");

client.close();

}

} catch (IOException e) {

Log.e(androidService.TAG, Thread.currentThread().getName()

+ "---->" + "read write error333333");

e.printStackTrace();

}

}

}

/**

* 功能:从socket流中读取完整文件数据

*

* InputStream in:socket输入流

*

* byte[] filelength: 流的前4个字节存储要转送的文件的字节数

*

* byte[] fileformat:流的前5-8字节存储要转送的文件的格式(如.apk)

*

* */

public static byte[] receiveFileFromSocket(InputStream in,

OutputStream out, byte[] filelength, byte[] fileformat) {

byte[] filebytes = null;// 文件数据

try {

in.read(filelength);// 读文件长度

int filelen = MyUtil.bytesToInt(filelength);// 文件长度从4字节byte[]转成Int

String strtmp = "read file length ok:" + filelen;

out.write(strtmp.getBytes("utf-8"));

out.flush();

filebytes = new byte[filelen];

int pos = 0;

int rcvLen = 0;

while ((rcvLen = in.read(filebytes, pos, filelen - pos)) > 0) {

pos += rcvLen;

}

Log.v(androidService.TAG, Thread.currentThread().getName()

+ "---->" + "read file OK:file size=" + filebytes.length);

out.write("read file ok".getBytes("utf-8"));

out.flush();

} catch (Exception e) {

Log.v(androidService.TAG, Thread.currentThread().getName()

+ "---->" + "receiveFileFromSocket error");

e.printStackTrace();

}

return filebytes;

}

/* 读取命令 */

public static String readCMDFromSocket(InputStream in) {

int MAX_BUFFER_BYTES = 2048;

String msg = "";

byte[] tempbuffer = new byte[MAX_BUFFER_BYTES];

try {

int numReadedBytes = in.read(tempbuffer, 0, tempbuffer.length);

msg = new String(tempbuffer, 0, numReadedBytes, "utf-8");

tempbuffer = null;

} catch (Exception e) {

Log.v(androidService.TAG, Thread.currentThread().getName()

+ "---->" + "readFromSocket error");

e.printStackTrace();

}

// Log.v(Service139.TAG, "msg=" + msg);

return msg;

}

}

后面是两个辅助类:

view plaincopy to clipboardprint?

package com.otheri.util;

import java.io.BufferedInputStream;

import java.io.File;

import java.io.FileInputStream;

import java.io.FileOutputStream;

import java.io.IOException;

import com.otheri.service.androidService;

import android.util.Log;

public class FileHelper {

// private static String FILEPATH = "/data/local/tmp";

private static String FILEPATH = "/sdcard";

// private static String FILEPATH = "/tmp";

public static File newFile(String fileName) {

File file = null;

try {

file = new File(FILEPATH, fileName);

file.delete();

file.createNewFile();

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

return file;

}

public static void writeFile(File file, byte[] data, int offset, int count)

throws IOException {

FileOutputStream fos = new FileOutputStream(file, true);

fos.write(data, offset, count);

fos.flush();

fos.close();

}

public static byte[] readFile(String fileName) throws IOException {

File file = new File(FILEPATH, fileName);

file.createNewFile();

FileInputStream fis = new FileInputStream(file);

BufferedInputStream bis = new BufferedInputStream(fis);

int leng = bis.available();

Log.v(androidService.TAG, "filesize = " + leng);

byte[] b = new byte[leng];

bis.read(b, 0, leng);

// Input in = new Input(fis);

// byte[] ret = in.readAll();

// in.close();

bis.close();

return b;

}

}

package com.otheri.util;

import java.io.BufferedInputStream;

import java.io.File;

import java.io.FileInputStream;

import java.io.FileOutputStream;

import java.io.IOException;

import com.otheri.service.androidService;

import android.util.Log;

public class FileHelper {

// private static String FILEPATH = "/data/local/tmp";

private static String FILEPATH = "/sdcard";

// private static String FILEPATH = "/tmp";

public static File newFile(String fileName) {

File file = null;

try {

file = new File(FILEPATH, fileName);

file.delete();

file.createNewFile();

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

return file;

}

public static void writeFile(File file, byte[] data, int offset, int count)

throws IOException {

FileOutputStream fos = new FileOutputStream(file, true);

fos.write(data, offset, count);

fos.flush();

fos.close();

}

public static byte[] readFile(String fileName) throws IOException {

File file = new File(FILEPATH, fileName);

file.createNewFile();

FileInputStream fis = new FileInputStream(file);

BufferedInputStream bis = new BufferedInputStream(fis);

int leng = bis.available();

Log.v(androidService.TAG, "filesize = " + leng);

byte[] b = new byte[leng];

bis.read(b, 0, leng);

// Input in = new Input(fis);

// byte[] ret = in.readAll();

// in.close();

bis.close();

return b;

}

}

view plaincopy to clipboardprint?

package com.otheri.util;

import java.io.InputStream;

import android.util.Log;

import com.otheri.service.androidService;

public class MyUtil {

/* byte[]转Int */

public static int bytesToInt(byte[] bytes) {

int addr = bytes[0] & 0xFF;

addr |= ((bytes[1] << 8) & 0xFF00);

addr |= ((bytes[2] << 16) & 0xFF0000);

addr |= ((bytes[3] << 24) & 0xFF000000);

return addr;

}

/* Int转byte[] */

public static byte[] intToByte(int i) {

byte[] abyte0 = new byte[4];

abyte0[0] = (byte) (0xff & i);

abyte0[1] = (byte) ((0xff00 & i) >> 8);

abyte0[2] = (byte) ((0xff0000 & i) >> 16);

abyte0[3] = (byte) ((0xff000000 & i) >> 24);

return abyte0;

}

}

0

评论区