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 plain  copy
  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 plain  copy
  1. Runtime.getRuntime().exec(  
  2. "adb shell am broadcast -a NotifyServiceStart");  

 android端的代码:ServiceBroadcastReceiver.java

 

 

[java]  view plain  copy
  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 plain  copy
  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 plain  copy
  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 plain  copy
  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 plain  copy
  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 plain  copy
  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 plain  copy
  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 plain  copy
  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 plain  copy
  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. }  

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android 上实现 Socket 客户端服务端通信,可以通过 Java 的 Socket 编程实现。下面是一个简单的示例: 1. 服务端代码: ```java import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; public class Server { public static void main(String[] args) throws IOException { ServerSocket serverSocket = new ServerSocket(8888); System.out.println("服务器已启动,等待客户端连接..."); while (true) { Socket socket = serverSocket.accept(); System.out.println("客户端已连接:" + socket.getInetAddress()); Thread thread = new Thread(new ServerThread(socket)); thread.start(); } } } ``` 2. 服务端线程代码: ```java import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.Socket; public class ServerThread implements Runnable { private Socket socket; public ServerThread(Socket socket) { this.socket = socket; } @Override public void run() { try { BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream())); String str; while ((str = reader.readLine()) != null) { System.out.println("客户端发送消息:" + str); } } catch (IOException e) { e.printStackTrace(); } } } ``` 3. 客户端代码: ```java import java.io.IOException; import java.io.OutputStream; import java.net.Socket; import java.net.UnknownHostException; public class Client { public static void main(String[] args) throws UnknownHostException, IOException { Socket socket = new Socket("localhost", 8888); OutputStream outputStream = socket.getOutputStream(); outputStream.write("Hello Server".getBytes()); outputStream.flush(); socket.shutdownOutput(); socket.close(); } } ``` 在服务端启动后,等待客户端连接,当客户端连接后,开启一个线程处理客户端的请求。客户端通过 Socket 连接到服务端,发送消息后关闭连接。 注意:以上代码仅为示例,没有进行异常处理等操作,实际使用时需要根据具体需求补充完整。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值