zoukankan      html  css  js  c++  java
  • 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”

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

    [java] view plaincopy
     
    1. Runtime.getRuntime().exec("adb forward tcp:12580 tcp:10086");  
    2.             Thread.sleep(3000);  

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

         

        pc端命令:

      

    [java] view plaincopy
     
    1. Runtime.getRuntime().exec(  
    2. "adb shell am broadcast -a NotifyServiceStart");  

     android端的代码:ServiceBroadcastReceiver.java

    [java] view plaincopy
     
    1. package com.otheri.service;  
    2.   
    3. import android.content.BroadcastReceiver;  
    4. import android.content.Context;  
    5. import android.content.Intent;  
    6. import android.util.Log;  
    7.   
    8. public class ServiceBroadcastReceiver extends BroadcastReceiver {  
    9.     private static String START_ACTION = "NotifyServiceStart";  
    10.     private static String STOP_ACTION = "NotifyServiceStop";  
    11.   
    12.     @Override  
    13.     public void onReceive(Context context, Intent intent) {  
    14.         Log.d(androidService.TAG, Thread.currentThread().getName() + "---->"  
    15.                 + "ServiceBroadcastReceiver onReceive");  
    16.   
    17.         String action = intent.getAction();  
    18.         if (START_ACTION.equalsIgnoreCase(action)) {  
    19.             context.startService(new Intent(context, androidService.class));  
    20.   
    21.             Log.d(androidService.TAG, Thread.currentThread().getName() + "---->"  
    22.                     + "ServiceBroadcastReceiver onReceive start end");  
    23.         } else if (STOP_ACTION.equalsIgnoreCase(action)) {  
    24.             context.stopService(new Intent(context, androidService.class));  
    25.             Log.d(androidService.TAG, Thread.currentThread().getName() + "---->"  
    26.                     + "ServiceBroadcastReceiver onReceive stop end");  
    27.         }  
    28.     }  
    29.   
    30. }  

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

        android的代码:

    [java] view plaincopy
     
    1. public void run() {  
    2.         Log.d(androidService.TAG, Thread.currentThread().getName() + "---->"  
    3.                 + "a client has connected to server!");  
    4.         BufferedOutputStream out;  
    5.         BufferedInputStream in;  
    6.         try {  
    7.             /* PC端发来的数据msg */  
    8.             String currCMD = "";  
    9.             out = new BufferedOutputStream(client.getOutputStream());  
    10.             in = new BufferedInputStream(client.getInputStream());  
    11.             // testSocket();// 测试socket方法  
    12.             androidService.ioThreadFlag = true;  
    13.             while (androidService.ioThreadFlag) {  
    14.                 try {  
    15.                     if (!client.isConnected()) {  
    16.                         break;  
    17.                     }  
    18.   
    19.                     /* 接收PC发来的数据 */  
    20.                     Log.v(androidService.TAG, Thread.currentThread().getName()  
    21.                             + "---->" + "will read......");  
    22.                     /* 读操作命令 */  
    23.                     currCMD = readCMDFromSocket(in);  
    24.                     Log.v(androidService.TAG, Thread.currentThread().getName()  
    25.                             + "---->" + "**currCMD ==== " + currCMD);  
    26.   
    27.                     /* 根据命令分别处理数据 */  
    28.                     if (currCMD.equals("1")) {  
    29.                         out.write("OK".getBytes());  
    30.                         out.flush();  
    31.                     } else if (currCMD.equals("2")) {  
    32.                         out.write("OK".getBytes());  
    33.                         out.flush();  
    34.                     } else if (currCMD.equals("3")) {  
    35.                         out.write("OK".getBytes());  
    36.                         out.flush();  
    37.                     } else if (currCMD.equals("4")) {  
    38.                         /* 准备接收文件数据 */  
    39.                         try {  
    40.                             out.write("service receive OK".getBytes());  
    41.                             out.flush();  
    42.                         } catch (IOException e) {  
    43.                             e.printStackTrace();  
    44.                         }  
    45.   
    46.                         /* 接收文件数据,4字节文件长度,4字节文件格式,其后是文件数据 */  
    47.                         byte[] filelength = new byte[4];  
    48.                         byte[] fileformat = new byte[4];  
    49.                         byte[] filebytes = null;  
    50.   
    51.                         /* 从socket流中读取完整文件数据 */  
    52.                         filebytes = receiveFileFromSocket(in, out, filelength,  
    53.                                 fileformat);  
    54.   
    55.                         // Log.v(Service139.TAG, "receive data =" + new  
    56.                         // String(filebytes));  
    57.                         try {  
    58.                             /* 生成文件 */  
    59.                             File file = FileHelper.newFile("R0013340.JPG");  
    60.                             FileHelper.writeFile(file, filebytes, 0,  
    61.                                     filebytes.length);  
    62.                         } catch (IOException e) {  
    63.                             e.printStackTrace();  
    64.                         }  
    65.                     } else if (currCMD.equals("exit")) {  
    66.   
    67.                     }  
    68.                 } catch (Exception e) {  
    69.                     // try {  
    70.                     // out.write("error".getBytes("utf-8"));  
    71.                     // out.flush();  
    72.                     // } catch (IOException e1) {  
    73.                     // e1.printStackTrace();  
    74.                     // }  
    75.                     Log.e(androidService.TAG, Thread.currentThread().getName()  
    76.                             + "---->" + "read write error111111");  
    77.                 }  
    78.             }  
    79.             out.close();  
    80.             in.close();  
    81.         } catch (Exception e) {  
    82.             Log.e(androidService.TAG, Thread.currentThread().getName()  
    83.                     + "---->" + "read write error222222");  
    84.             e.printStackTrace();  
    85.         } finally {  
    86.             try {  
    87.                 if (client != null) {  
    88.                     Log.v(androidService.TAG, Thread.currentThread().getName()  
    89.                             + "---->" + "client.close()");  
    90.                     client.close();  
    91.                 }  
    92.             } catch (IOException e) {  
    93.                 Log.e(androidService.TAG, Thread.currentThread().getName()  
    94.                         + "---->" + "read write error333333");  
    95.                 e.printStackTrace();  
    96.             }  
    97.         }  

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

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

       android端接收数据的代码:

    [java] view plaincopy
     
    1. /** 
    2.      * 功能:从socket流中读取完整文件数据 
    3.      *  
    4.      * InputStream in:socket输入流 
    5.      *  
    6.      * byte[] filelength: 流的前4个字节存储要转送的文件的字节数 
    7.      *  
    8.      * byte[] fileformat:流的前5-8字节存储要转送的文件的格式(如.apk) 
    9.      *  
    10.      * */  
    11.     public static byte[] receiveFileFromSocket(InputStream in,  
    12.             OutputStream out, byte[] filelength, byte[] fileformat) {  
    13.         byte[] filebytes = null;// 文件数据  
    14.         try {  
    15.             int filelen = MyUtil.bytesToInt(filelength);// 文件长度从4字节byte[]转成Int  
    16.             String strtmp = "read file length ok:" + filelen;  
    17.             out.write(strtmp.getBytes("utf-8"));  
    18.             out.flush();  
    19.   
    20.             filebytes = new byte[filelen];  
    21.             int pos = 0;  
    22.             int rcvLen = 0;  
    23.             while ((rcvLen = in.read(filebytes, pos, filelen - pos)) > 0) {  
    24.                 pos += rcvLen;  
    25.             }  
    26.             Log.v(androidService.TAG, Thread.currentThread().getName()  
    27.                     + "---->" + "read file OK:file size=" + filebytes.length);  
    28.             out.write("read file ok".getBytes("utf-8"));  
    29.             out.flush();  
    30.         } catch (Exception e) {  
    31.             Log.v(androidService.TAG, Thread.currentThread().getName()  
    32.                     + "---->" + "receiveFileFromSocket error");  
    33.             e.printStackTrace();  
    34.         }  
    35.         return filebytes;  
    36.     }  

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

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

    源码:

    客户端(pc端):

    testPcClient.java

    [java] view plaincopy
     
    1. import java.io.BufferedInputStream;  
    2. import java.io.BufferedOutputStream;  
    3. import java.io.BufferedReader;  
    4. import java.io.ByteArrayOutputStream;  
    5. import java.io.IOException;  
    6. import java.io.InputStream;  
    7. import java.io.InputStreamReader;  
    8. import java.net.InetAddress;  
    9. import java.net.Socket;  
    10. import java.net.UnknownHostException;  
    11.   
    12. public class testPcClient {  
    13.   
    14.     /** 
    15.      * @param args 
    16.      * @throws InterruptedException 
    17.      */  
    18.     public static void main(String[] args) throws InterruptedException {  
    19.         try {  
    20.             Runtime.getRuntime().exec(  
    21.                     "adb shell am broadcast -a NotifyServiceStop");  
    22.             Thread.sleep(3000);  
    23.             Runtime.getRuntime().exec("adb forward tcp:12580 tcp:10086");  
    24.             Thread.sleep(3000);  
    25.             Runtime.getRuntime().exec(  
    26.                     "adb shell am broadcast -a NotifyServiceStart");  
    27.             Thread.sleep(3000);  
    28.         } catch (IOException e3) {  
    29.             e3.printStackTrace();  
    30.         }  
    31.   
    32.         Socket socket = null;  
    33.         try {  
    34.             InetAddress serverAddr = null;  
    35.             serverAddr = InetAddress.getByName("127.0.0.1");  
    36.             System.out.println("TCP 1111" + "C: Connecting...");  
    37.             socket = new Socket(serverAddr, 12580);  
    38.             String str = "hi,wufenglong";  
    39.             System.out.println("TCP 221122" + "C:RECEIVE");  
    40.             BufferedOutputStream out = new BufferedOutputStream(socket  
    41.                     .getOutputStream());  
    42.             BufferedInputStream in = new BufferedInputStream(socket  
    43.                     .getInputStream());  
    44.             BufferedReader br = new BufferedReader(new InputStreamReader(  
    45.                     System.in));  
    46.             boolean flag = true;  
    47.             while (flag) {  
    48.                 System.out.print("请输入1~6的数字,退出输入exit:");  
    49.                 String strWord = br.readLine();// 从控制台输入1~6  
    50.                 if (strWord.equals("1")) {  
    51.                     out.write("1".getBytes());  
    52.                     out.flush();  
    53.                     System.out.println("1 finish sending the data");  
    54.                     String strFormsocket = readFromSocket(in);  
    55.                     System.out.println("the data sent by server is:/r/n"  
    56.                             + strFormsocket);  
    57.                     System.out  
    58.                             .println("=============================================");  
    59.                 } else if (strWord.equals("2")) {  
    60.                     out.write("2".getBytes());  
    61.                     out.flush();  
    62.                     System.out.println("2 finish sending the data");  
    63.                     String strFormsocket = readFromSocket(in);  
    64.                     System.out.println("the data sent by server is:/r/n"  
    65.                             + strFormsocket);  
    66.                     System.out  
    67.                             .println("=============================================");  
    68.                 } else if (strWord.equals("3")) {  
    69.                     out.write("3".getBytes());  
    70.                     out.flush();  
    71.                     System.out.println("3 finish sending the data");  
    72.                     String strFormsocket = readFromSocket(in);  
    73.                     System.out.println("the data sent by server is:/r/n"  
    74.                             + strFormsocket);  
    75.                     System.out  
    76.                             .println("=============================================");  
    77.                 } else if (strWord.equals("4")) {  
    78.                     /* 发送命令 */  
    79.                     out.write("4".getBytes());  
    80.                     out.flush();  
    81.                     System.out.println("send file finish sending the CMD:");  
    82.                     /* 服务器反馈:准备接收 */  
    83.                     String strFormsocket = readFromSocket(in);  
    84.                     System.out  
    85.                             .println("service ready receice data:UPDATE_CONTACTS:"  
    86.                                     + strFormsocket);  
    87.                     byte[] filebytes = FileHelper.readFile("R0013340.JPG");  
    88.                     System.out.println("file size=" + filebytes.length);  
    89.                     /* 将整数转成4字节byte数组 */  
    90.                     byte[] filelength = new byte[4];  
    91.                     filelength = tools.intToByte(filebytes.length);  
    92.                     /* 将.apk字符串转成4字节byte数组 */  
    93.                     byte[] fileformat = null;  
    94.                     fileformat = ".apk".getBytes();  
    95.                     System.out  
    96.                             .println("fileformat length=" + fileformat.length);  
    97.                     /* 字节流中前4字节为文件长度,4字节文件格式,以后是文件流 */  
    98.                     /* 注意如果write里的byte[]超过socket的缓存,系统自动分包写过去,所以对方要循环写完 */  
    99.                     out.write(filelength);  
    100.                     out.flush();  
    101.                     String strok1 = readFromSocket(in);  
    102.                     System.out.println("service receive filelength :" + strok1);  
    103.                     // out.write(fileformat);  
    104.                     // out.flush();  
    105.                     // String strok2 = readFromSocket(in);  
    106.                     // System.out.println("service receive fileformat :" +  
    107.                     // strok2);  
    108.                     System.out.println("write data to android");  
    109.                     out.write(filebytes);  
    110.                     out.flush();  
    111.                     System.out.println("*********");  
    112.   
    113.                     /* 服务器反馈:接收成功 */  
    114.                     String strread = readFromSocket(in);  
    115.                     System.out.println(" send data success:" + strread);  
    116.                     System.out  
    117.                             .println("=============================================");  
    118.                 } else if (strWord.equalsIgnoreCase("EXIT")) {  
    119.                     out.write("EXIT".getBytes());  
    120.                     out.flush();  
    121.                     System.out.println("EXIT finish sending the data");  
    122.                     String strFormsocket = readFromSocket(in);  
    123.                     System.out.println("the data sent by server is:/r/n"  
    124.                             + strFormsocket);  
    125.                     flag = false;  
    126.                     System.out  
    127.                             .println("=============================================");  
    128.                 }  
    129.             }  
    130.   
    131.         } catch (UnknownHostException e1) {  
    132.             System.out.println("TCP 331133" + "ERROR:" + e1.toString());  
    133.         } catch (Exception e2) {  
    134.             System.out.println("TCP 441144" + "ERROR:" + e2.toString());  
    135.         } finally {  
    136.             try {  
    137.                 if (socket != null) {  
    138.                     socket.close();  
    139.                     System.out.println("socket.close()");  
    140.                 }  
    141.             } catch (IOException e) {  
    142.                 System.out.println("TCP 5555" + "ERROR:" + e.toString());  
    143.             }  
    144.         }  
    145.     }  
    146.   
    147.     /* 从InputStream流中读数据 */  
    148.     public static String readFromSocket(InputStream in) {  
    149.         int MAX_BUFFER_BYTES = 4000;  
    150.         String msg = "";  
    151.         byte[] tempbuffer = new byte[MAX_BUFFER_BYTES];  
    152.         try {  
    153.             int numReadedBytes = in.read(tempbuffer, 0, tempbuffer.length);  
    154.             msg = new String(tempbuffer, 0, numReadedBytes, "utf-8");  
    155.   
    156.             tempbuffer = null;  
    157.         } catch (Exception e) {  
    158.             e.printStackTrace();  
    159.         }  
    160.         // Log.v(Service139.TAG, "msg=" + msg);  
    161.         return msg;  
    162.     }  
    163. }  

    android服务器端:

    主类androidService.java

    [java] view plaincopy
     
    1. package com.otheri.service;  
    2.   
    3. import java.io.File;  
    4. import java.io.IOException;  
    5. import java.net.ServerSocket;  
    6. import java.net.Socket;  
    7.   
    8. import android.app.Service;  
    9. import android.content.BroadcastReceiver;  
    10. import android.content.Context;  
    11. import android.content.Intent;  
    12. import android.content.IntentFilter;  
    13. import android.os.IBinder;  
    14. import android.util.Log;  
    15.   
    16. /** 
    17.  * 设置:android手机 
    18.  *  
    19.  *  
    20.  * */  
    21. public class androidService extends Service {  
    22.     public static final String TAG = "TAG";  
    23.     public static Boolean mainThreadFlag = true;  
    24.     public static Boolean ioThreadFlag = true;  
    25.     ServerSocket serverSocket = null;  
    26.     final int SERVER_PORT = 10086;  
    27.     File testFile;  
    28.     private sysBroadcastReceiver sysBR;  
    29.   
    30.     @Override  
    31.     public void onCreate() {  
    32.         super.onCreate();  
    33.         Log.v(TAG, Thread.currentThread().getName() + "---->" + "  onCreate");  
    34.         /* 创建内部类sysBroadcastReceiver 并注册registerReceiver */  
    35.         sysRegisterReceiver();  
    36.         new Thread() {  
    37.             public void run() {  
    38.                 doListen();  
    39.             };  
    40.         }.start();  
    41.     }  
    42.   
    43.     private void doListen() {  
    44.         Log.d(TAG, Thread.currentThread().getName() + "---->"  
    45.                 + " doListen() START");  
    46.         serverSocket = null;  
    47.         try {  
    48.             Log.d(TAG, Thread.currentThread().getName() + "---->"  
    49.                     + " doListen() new serverSocket");  
    50.             serverSocket = new ServerSocket(SERVER_PORT);  
    51.   
    52.             boolean mainThreadFlag = true;  
    53.             while (mainThreadFlag) {  
    54.                 Log.d(TAG, Thread.currentThread().getName() + "---->"  
    55.                         + " doListen() listen");  
    56.   
    57.                 Socket client = serverSocket.accept();  
    58.   
    59.                 new Thread(new ThreadReadWriterIOSocket(this, client)).start();  
    60.             }  
    61.         } catch (IOException e1) {  
    62.             Log.v(androidService.TAG, Thread.currentThread().getName()  
    63.                     + "---->" + "new serverSocket error");  
    64.             e1.printStackTrace();  
    65.         }  
    66.     }  
    67.   
    68.     /* 创建内部类sysBroadcastReceiver 并注册registerReceiver */  
    69.     private void sysRegisterReceiver() {  
    70.         Log.v(TAG, Thread.currentThread().getName() + "---->"  
    71.                 + "sysRegisterReceiver");  
    72.         sysBR = new sysBroadcastReceiver();  
    73.         /* 注册BroadcastReceiver */  
    74.         IntentFilter filter1 = new IntentFilter();  
    75.         /* 新的应用程序被安装到了设备上的广播 */  
    76.         filter1.addAction("android.intent.action.PACKAGE_ADDED");  
    77.         filter1.addDataScheme("package");  
    78.         filter1.addAction("android.intent.action.PACKAGE_REMOVED");  
    79.         filter1.addDataScheme("package");  
    80.         registerReceiver(sysBR, filter1);  
    81.     }  
    82.   
    83.     /* 内部类:BroadcastReceiver 用于接收系统事件 */  
    84.     private class sysBroadcastReceiver extends BroadcastReceiver {  
    85.   
    86.         @Override  
    87.         public void onReceive(Context context, Intent intent) {  
    88.             String action = intent.getAction();  
    89.             if (action.equalsIgnoreCase("android.intent.action.PACKAGE_ADDED")) {  
    90.                 // ReadInstalledAPP();  
    91.             } else if (action  
    92.                     .equalsIgnoreCase("android.intent.action.PACKAGE_REMOVED")) {  
    93.                 // ReadInstalledAPP();  
    94.             }  
    95.             Log.v(TAG, Thread.currentThread().getName() + "---->"  
    96.                     + "sysBroadcastReceiver onReceive");  
    97.         }  
    98.     }  
    99.   
    100.     @Override  
    101.     public void onDestroy() {  
    102.         super.onDestroy();  
    103.   
    104.         // 关闭线程  
    105.         mainThreadFlag = false;  
    106.         ioThreadFlag = false;  
    107.         // 关闭服务器  
    108.         try {  
    109.             Log.v(TAG, Thread.currentThread().getName() + "---->"  
    110.                     + "serverSocket.close()");  
    111.             serverSocket.close();  
    112.         } catch (IOException e) {  
    113.             e.printStackTrace();  
    114.         }  
    115.         Log.v(TAG, Thread.currentThread().getName() + "---->"  
    116.                 + "**************** onDestroy****************");  
    117.     }  
    118.   
    119.     @Override  
    120.     public void onStart(Intent intent, int startId) {  
    121.         Log.d(TAG, Thread.currentThread().getName() + "---->" + " onStart()");  
    122.         super.onStart(intent, startId);  
    123.   
    124.     }  
    125.   
    126.     @Override  
    127.     public IBinder onBind(Intent arg0) {  
    128.         Log.d(TAG, "  onBind");  
    129.         return null;  
    130.     }  
    131.   
    132. }  

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

    [java] view plaincopy
     
    1. package com.otheri.service;  
    2.   
    3. import android.content.BroadcastReceiver;  
    4. import android.content.Context;  
    5. import android.content.Intent;  
    6. import android.util.Log;  
    7.   
    8. public class ServiceBroadcastReceiver extends BroadcastReceiver {  
    9.     private static String START_ACTION = "NotifyServiceStart";  
    10.     private static String STOP_ACTION = "NotifyServiceStop";  
    11.   
    12.     @Override  
    13.     public void onReceive(Context context, Intent intent) {  
    14.         Log.d(androidService.TAG, Thread.currentThread().getName() + "---->"  
    15.                 + "ServiceBroadcastReceiver onReceive");  
    16.   
    17.         String action = intent.getAction();  
    18.         if (START_ACTION.equalsIgnoreCase(action)) {  
    19.             context.startService(new Intent(context, androidService.class));  
    20.   
    21.             Log.d(androidService.TAG, Thread.currentThread().getName() + "---->"  
    22.                     + "ServiceBroadcastReceiver onReceive start end");  
    23.         } else if (STOP_ACTION.equalsIgnoreCase(action)) {  
    24.             context.stopService(new Intent(context, androidService.class));  
    25.             Log.d(androidService.TAG, Thread.currentThread().getName() + "---->"  
    26.                     + "ServiceBroadcastReceiver onReceive stop end");  
    27.         }  
    28.     }  
    29.   
    30. }  

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

    [java] view plaincopy
     
    1. package com.otheri.service;  
    2.   
    3. import java.io.BufferedInputStream;  
    4. import java.io.BufferedOutputStream;  
    5. import java.io.ByteArrayOutputStream;  
    6. import java.io.File;  
    7. import java.io.IOException;  
    8. import java.io.InputStream;  
    9. import java.io.OutputStream;  
    10. import java.net.Socket;  
    11.   
    12. import android.content.Context;  
    13. import android.util.Log;  
    14.   
    15. import com.otheri.util.FileHelper;  
    16. import com.otheri.util.MyUtil;  
    17.   
    18. /** 
    19.  * 功能:用于socket的交互 
    20.  *  
    21.  * @author wufenglong 
    22.  *  
    23.  */  
    24. public class ThreadReadWriterIOSocket implements Runnable {  
    25.     private Socket client;  
    26.     private Context context;  
    27.   
    28.     ThreadReadWriterIOSocket(Context context, Socket client) {  
    29.   
    30.         this.client = client;  
    31.         this.context = context;  
    32.     }  
    33.   
    34.     @Override  
    35.     public void run() {  
    36.         Log.d(androidService.TAG, Thread.currentThread().getName() + "---->"  
    37.                 + "a client has connected to server!");  
    38.         BufferedOutputStream out;  
    39.         BufferedInputStream in;  
    40.         try {  
    41.             /* PC端发来的数据msg */  
    42.             String currCMD = "";  
    43.             out = new BufferedOutputStream(client.getOutputStream());  
    44.             in = new BufferedInputStream(client.getInputStream());  
    45.             // testSocket();// 测试socket方法  
    46.             androidService.ioThreadFlag = true;  
    47.             while (androidService.ioThreadFlag) {  
    48.                 try {  
    49.                     if (!client.isConnected()) {  
    50.                         break;  
    51.                     }  
    52.   
    53.                     /* 接收PC发来的数据 */  
    54.                     Log.v(androidService.TAG, Thread.currentThread().getName()  
    55.                             + "---->" + "will read......");  
    56.                     /* 读操作命令 */  
    57.                     currCMD = readCMDFromSocket(in);  
    58.                     Log.v(androidService.TAG, Thread.currentThread().getName()  
    59.                             + "---->" + "**currCMD ==== " + currCMD);  
    60.   
    61.                     /* 根据命令分别处理数据 */  
    62.                     if (currCMD.equals("1")) {  
    63.                         out.write("OK".getBytes());  
    64.                         out.flush();  
    65.                     } else if (currCMD.equals("2")) {  
    66.                         out.write("OK".getBytes());  
    67.                         out.flush();  
    68.                     } else if (currCMD.equals("3")) {  
    69.                         out.write("OK".getBytes());  
    70.                         out.flush();  
    71.                     } else if (currCMD.equals("4")) {  
    72.                         /* 准备接收文件数据 */  
    73.                         try {  
    74.                             out.write("service receive OK".getBytes());  
    75.                             out.flush();  
    76.                         } catch (IOException e) {  
    77.                             e.printStackTrace();  
    78.                         }  
    79.   
    80.                         /* 接收文件数据,4字节文件长度,4字节文件格式,其后是文件数据 */  
    81.                         byte[] filelength = new byte[4];  
    82.                         byte[] fileformat = new byte[4];  
    83.                         byte[] filebytes = null;  
    84.   
    85.                         /* 从socket流中读取完整文件数据 */  
    86.                         filebytes = receiveFileFromSocket(in, out, filelength,  
    87.                                 fileformat);  
    88.   
    89.                         // Log.v(Service139.TAG, "receive data =" + new  
    90.                         // String(filebytes));  
    91.                         try {  
    92.                             /* 生成文件 */  
    93.                             File file = FileHelper.newFile("R0013340.JPG");  
    94.                             FileHelper.writeFile(file, filebytes, 0,  
    95.                                     filebytes.length);  
    96.                         } catch (IOException e) {  
    97.                             e.printStackTrace();  
    98.                         }  
    99.                     } else if (currCMD.equals("exit")) {  
    100.   
    101.                     }  
    102.                 } catch (Exception e) {  
    103.                     // try {  
    104.                     // out.write("error".getBytes("utf-8"));  
    105.                     // out.flush();  
    106.                     // } catch (IOException e1) {  
    107.                     // e1.printStackTrace();  
    108.                     // }  
    109.                     Log.e(androidService.TAG, Thread.currentThread().getName()  
    110.                             + "---->" + "read write error111111");  
    111.                 }  
    112.             }  
    113.             out.close();  
    114.             in.close();  
    115.         } catch (Exception e) {  
    116.             Log.e(androidService.TAG, Thread.currentThread().getName()  
    117.                     + "---->" + "read write error222222");  
    118.             e.printStackTrace();  
    119.         } finally {  
    120.             try {  
    121.                 if (client != null) {  
    122.                     Log.v(androidService.TAG, Thread.currentThread().getName()  
    123.                             + "---->" + "client.close()");  
    124.                     client.close();  
    125.                 }  
    126.             } catch (IOException e) {  
    127.                 Log.e(androidService.TAG, Thread.currentThread().getName()  
    128.                         + "---->" + "read write error333333");  
    129.                 e.printStackTrace();  
    130.             }  
    131.         }  
    132.     }  
    133.   
    134.     /** 
    135.      * 功能:从socket流中读取完整文件数据 
    136.      *  
    137.      * InputStream in:socket输入流 
    138.      *  
    139.      * byte[] filelength: 流的前4个字节存储要转送的文件的字节数 
    140.      *  
    141.      * byte[] fileformat:流的前5-8字节存储要转送的文件的格式(如.apk) 
    142.      *  
    143.      * */  
    144.     public static byte[] receiveFileFromSocket(InputStream in,  
    145.             OutputStream out, byte[] filelength, byte[] fileformat) {  
    146.         byte[] filebytes = null;// 文件数据  
    147.         try {  
    148.             in.read(filelength);// 读文件长度  
    149.             int filelen = MyUtil.bytesToInt(filelength);// 文件长度从4字节byte[]转成Int  
    150.             String strtmp = "read file length ok:" + filelen;  
    151.             out.write(strtmp.getBytes("utf-8"));  
    152.             out.flush();  
    153.   
    154.             filebytes = new byte[filelen];  
    155.             int pos = 0;  
    156.             int rcvLen = 0;  
    157.             while ((rcvLen = in.read(filebytes, pos, filelen - pos)) > 0) {  
    158.                 pos += rcvLen;  
    159.             }  
    160.             Log.v(androidService.TAG, Thread.currentThread().getName()  
    161.                     + "---->" + "read file OK:file size=" + filebytes.length);  
    162.             out.write("read file ok".getBytes("utf-8"));  
    163.             out.flush();  
    164.         } catch (Exception e) {  
    165.             Log.v(androidService.TAG, Thread.currentThread().getName()  
    166.                     + "---->" + "receiveFileFromSocket error");  
    167.             e.printStackTrace();  
    168.         }  
    169.         return filebytes;  
    170.     }  
    171.   
    172.     /* 读取命令 */  
    173.     public static String readCMDFromSocket(InputStream in) {  
    174.         int MAX_BUFFER_BYTES = 2048;  
    175.         String msg = "";  
    176.         byte[] tempbuffer = new byte[MAX_BUFFER_BYTES];  
    177.         try {  
    178.             int numReadedBytes = in.read(tempbuffer, 0, tempbuffer.length);  
    179.             msg = new String(tempbuffer, 0, numReadedBytes, "utf-8");  
    180.             tempbuffer = null;  
    181.         } catch (Exception e) {  
    182.             Log.v(androidService.TAG, Thread.currentThread().getName()  
    183.                     + "---->" + "readFromSocket error");  
    184.             e.printStackTrace();  
    185.         }  
    186.         // Log.v(Service139.TAG, "msg=" + msg);  
    187.         return msg;  
    188.     }  
    189. }  

    后面是两个辅助类:

    [java] view plaincopy
     
    1. package com.otheri.util;  
    2.   
    3. import java.io.BufferedInputStream;  
    4. import java.io.File;  
    5. import java.io.FileInputStream;  
    6. import java.io.FileOutputStream;  
    7. import java.io.IOException;  
    8.   
    9. import com.otheri.service.androidService;  
    10.   
    11. import android.util.Log;  
    12.   
    13. public class FileHelper {  
    14.     // private static String FILEPATH = "/data/local/tmp";  
    15.   
    16.     private static String FILEPATH = "/sdcard";  
    17.   
    18.     // private static String FILEPATH = "/tmp";  
    19.   
    20.     public static File newFile(String fileName) {  
    21.         File file = null;  
    22.         try {  
    23.             file = new File(FILEPATH, fileName);  
    24.             file.delete();  
    25.             file.createNewFile();  
    26.         } catch (IOException e) {  
    27.             // TODO Auto-generated catch block  
    28.             e.printStackTrace();  
    29.         }  
    30.         return file;  
    31.     }  
    32.   
    33.     public static void writeFile(File file, byte[] data, int offset, int count)  
    34.             throws IOException {  
    35.   
    36.         FileOutputStream fos = new FileOutputStream(file, true);  
    37.         fos.write(data, offset, count);  
    38.         fos.flush();  
    39.         fos.close();  
    40.     }  
    41.   
    42.     public static byte[] readFile(String fileName) throws IOException {  
    43.         File file = new File(FILEPATH, fileName);  
    44.         file.createNewFile();  
    45.         FileInputStream fis = new FileInputStream(file);  
    46.         BufferedInputStream bis = new BufferedInputStream(fis);  
    47.         int leng = bis.available();  
    48.         Log.v(androidService.TAG, "filesize = " + leng);  
    49.         byte[] b = new byte[leng];  
    50.         bis.read(b, 0, leng);  
    51.         // Input in = new Input(fis);  
    52.         // byte[] ret = in.readAll();  
    53.         // in.close();  
    54.         bis.close();  
    55.         return b;  
    56.   
    57.     }  
    58. }  
    [java] view plaincopy
     
    1. package com.otheri.util;  
    2.   
    3. import java.io.InputStream;  
    4.   
    5. import android.util.Log;  
    6.   
    7. import com.otheri.service.androidService;  
    8.   
    9. public class MyUtil {  
    10.     /* byte[]转Int */  
    11.     public static int bytesToInt(byte[] bytes) {  
    12.         int addr = bytes[0] & 0xFF;  
    13.         addr |= ((bytes[1] << 8) & 0xFF00);  
    14.         addr |= ((bytes[2] << 16) & 0xFF0000);  
    15.         addr |= ((bytes[3] << 24) & 0xFF000000);  
    16.         return addr;  
    17.     }  
    18.   
    19.     /* Int转byte[] */  
    20.     public static byte[] intToByte(int i) {  
    21.         byte[] abyte0 = new byte[4];  
    22.         abyte0[0] = (byte) (0xff & i);  
    23.         abyte0[1] = (byte) ((0xff00 & i) >> 8);  
    24.         abyte0[2] = (byte) ((0xff0000 & i) >> 16);  
    25.         abyte0[3] = (byte) ((0xff000000 & i) >> 24);  
    26.         return abyte0;  
    27.     }  
    28.   
    29.       
    30.       
    31.       
    32. }  

    需要的朋友们,可以回复留下邮箱,少时发送到你们的邮箱。

  • 相关阅读:
    简单的REST的框架实现
    将 Shiro 作为一个许可为基础的应用程序 五:password加密/解密Spring应用
    Java自注三进入
    hdu 4803 贪心/思维题
    SSH框架总结(框架分析+环境搭建+实例源代码下载)
    Rational Rose 2007 &amp;Rational Rose 2003 下载及破解方法和汉化文件下载
    hdu 5014 思维题/推理
    电脑蓝屏出现事件7000
    大豆生物柴油驱动的大巴斯(Bus)
    POJ 3481 &amp; HDU 1908 Double Queue (map运用)
  • 原文地址:https://www.cnblogs.com/ggzjj/p/2858701.html
Copyright © 2011-2022 走看看