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

    技术2022-05-19  22

    需求:

         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”

         3.要想联通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");  } }

      5.由于是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();   }  }

      6.如果是在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()那里等数据。

     9.还要让服务器端可以同时连接多个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;       }                          } 

     

    本文来自博客,转载请标明出处:http://blog.csdn.net/wufenglong/archive/2010/07/31/5778862.aspx


    最新回复(0)