• pc与Android进行USB通信

    2015-10-20 13:11:01
    需求:  1.一个android端的service后台... 2.PC端程序,作为socket的客户端,用于给android手机端发操作命令   难点分析:  1.手机一定要有adb模式,即插上USB线时马上提示的对话框选adb。好多对手机的操作都

    需求:

         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.

    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端命令:

      

    1. Runtime.getRuntime().exec(  
    2. "adb shell am broadcast -a NotifyServiceStart");  

     android端的代码:ServiceBroadcastReceiver.java

     

     

    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的代码:

    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端接收数据的代码:

    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

    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

     

    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

     

    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

    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. }  

     

    后面是两个辅助类:

    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. }  

     

    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. }  

    展开全文
  • Android与PC通信之 Socket ONE Goal ,ONE Passion! 给浦发银行做的一个项目,其中最让人头疼的一点是,要求必须使用usb数据线进行数据的交互.这就遇到两个问题: 1.由于每个pc端的ip不同 然而 pad端ip="127.0.0.1...

    Android端与PC通信之 Socket

    ONE Goal ,ONE Passion!

     给浦发银行做的一个项目,其中最让人头疼的一点是,要求必须使用usb数据线进行数据的交互.这就遇到两个问题:
     1.由于每个pc端的ip不同 然而 pad端ip="127.0.0.1",所以pad(android端)不能作为client端.要让pc作为client端主动发起请求连接.
    
     2.使用模拟器时通信一切正常,可是使用了pad进行测试时根本无法通信,问了公司老大,查了一些资料终于找到了其中的解决办法.
    
     使用虚拟机可以的原因也许是:虚拟机运行在pc电脑上,虚拟机内部做了一些处理. 可是使用真机时需要将pc上的端口转发来作为请求端口,这就需要是用adb命令进行转发操作
    

    第一. pc端转发操作:

       先做准备工作.将我们的adb路径配置到path中,否则的话会报错的.以为执行adb命令不是系统级别,是不能执行的一般我们的sdk中都有adb.exe文件.在sdk/platform-tools下.
       提供adb下载:http://download.csdn.net/detail/fengltxx/9305923
    

    1,先执行adb命令 这些命令在cmd命令行也可以执行

    //这句adb命令可以不用.执行下面两句也可以实现转发.只是为了避免重复开启service所以在转发端口前先stop一下 
    Runtime.getRuntime().exec("adb shell am broadcast -a NotifyServiceStop");
    //转发的关键代码
    Runtime.getRuntime().exec("adb forward tcp:5000 tcp:13000");
    Runtime.getRuntime().exec("adb shell am broadcast -a NotifyServiceStart");

    2,接下来就和普通的socket通信没有什么区别了

    try {
                final Socket client = new Socket("127.0.0.1", 5000);
    
                // 得到socket管道中的输出流--------------像手机端写数据
                final BufferedOutputStream out = new BufferedOutputStream(client
                        .getOutputStream());
                // 得到socket管道中的输人流--------------读取手机端的数据
                final BufferedInputStream in = new BufferedInputStream(client
                        .getInputStream());
    
                // 开启子线程去读去数据
    
                new Thread() {
                    @Override
                    public void run() {
    
                        try {
                            String readMsg = "";
                            while (true) {
                                try {
                                    if (!client.isConnected()) {
                                        break;
                                    }
       // 读到后台发送的消息 然后去处理
                                    readMsg = readMsgFromSocket(in);
                                    if (readMsg.length() == 0) {
    
        break;
                                    }
                                }           
                        // 将要返回的数据发送给pc 
                  out.write((readMsg + "1").getBytes());
                out.flush();
    
                                } catch (Exception e) {
                                    e.printStackTrace();
                                }
                            }
                            in.close();
                        } catch (Exception e) {
                            e.printStackTrace();
                        } finally {
                        }
    
                    }
                }.start();
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
      //一个读取输入流的方法
        public static String readMsgFromSocket(InputStream in) {
    
            String msg = "";
            byte[] tempbuffer = new byte[1024;
            try {
                int numReadedBytes = in.read(tempbuffer, 0, tempbuffer.length);
                msg = new String(tempbuffer, 0, numReadedBytes, "utf-8");
    
            } catch (Exception e) {
                e.printStackTrace();
            }
            return msg;
        }
    

    第二 android端关键代码:

      android端其实就方便多了,作为服务端我们只需要监听端口就可以了.
      关键代码如下:
    
    
        class SocketServerThread extends Thread {
    
            @Override
            public void run() {
                try {
                    Log.d("fy", "等待连接");
                    System.out.println("---------socket 通信线程----等待连接");
                    serverSocket = new ServerSocket(13000);
    
                    while (true) {
    
                        client = serverSocket.accept();
    
                        out = new BufferedOutputStream(client.getOutputStream());
    
    
    
                        // 开启子线程去读去数据
                        new Thread(new SocketReadThread(new BufferedInputStream(client.getInputStream()))).start();//另外开启一个线程去读数据
    
                    }
                } catch (IOException e) {
                    e.printStackTrace();
    
                }
            }
    
    //   暴露给外部调用写入流的方法  如:SocketServerThread.SendMsg(str)
            public void SendMsg(String msg) {
    
                String msg_1 = msg;      //回写给银行的数据
                try {
    
                    out.write(msg_1.getBytes("UTF-8"));
                    out.flush();
    
                } catch (IOException e) {
                    e.printStackTrace();
                }
    
            }
    
    
            class SocketReadThread implements Runnable {
    
                private BufferedInputStream in;
    
                public SocketReadThread(BufferedInputStream inStream) throws IOException {
    
                    this.in = inStream;
                }
    
                public void run() {
                    try {
                        String readMsg = "";
                        while (true) {
                            try {
                                if (!client.isConnected()) {
                                    break;
                                }
    
                                //   读到后台发送的消息  然后去处理
                                currCMD = readMsgFromSocket(in);
                                //    处理读到的消息(主要是身份证信息),然后保存在sp中;
    
                                if (currCMD.length() == 0) {
    
    
    
                                    break;
                                }
                                if (readMsg .equals("0002")) {  
                                }
              //  将要返回的数据发送给 pc
                                out.write((readMsg + "flag").getBytes());
                                out.flush();
    
    
      } catch (Exception e) {
                                e.printStackTrace();
                            }
                        }
                        in.close();
                    } catch (Exception e) {
                        e.printStackTrace();
                    } finally {
                    }
                }
    
                public String readMsgFromSocket(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");
    
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    return msg;
                }
            }
        }
    //有一些变量的声明没有给出来,很简单的东西不在写了.
    终于搞定了.把这快搞定浦发的项目基本就ok了.终于能歇歇了.哦!忘记一点.如果看端口有没有转发成功可以通过cmd命令行查看.
    netstat -ano | findstr "80" (注80是你想要看查看的端口号)

    如图则恭喜我们转发成功
    转发成功

    展开全文
  • 1.先安装node.js和express框架node.js安装:http://www.runoob.com/nodejs/nodejs-install-setup.htmlexpress安装和使用方式:http://www.expressjs.com.cn/starter/installing.html (建议全部看完,很容易上手)...

    1.先安装node.js和express框架

    node.js安装:http://www.runoob.com/nodejs/nodejs-install-setup.html

    express安装和使用方式:http://www.expressjs.com.cn/starter/installing.html  (建议全部看完,很容易上手)

    安装有时候会遇到一些问题,试着百度解决

    需要用到的框架安装

    npm install express   安装express

    npm install mysql    安装mysql

    2.安装数据库

    我使用的是mysql数据库,其他的数据库也可以,只不过在node.js中连接,操作数据库的方式不同,大同小异。


    3.先搭建一个服务器和连接数据库


    新建getdate.js    实现数据库的查询的操作

    var express = require('express');
    var router = express.Router();
    var mysql = require('mysql');
    var connection = mysql.createConnection({ //配置你本地的数据库
    host : 'localhost',
    user : 'root',
    password : '88888888',
    database : 'test'
    });

    // 该路由使用的中间件
    router.use(function timeLog(req, res, next) {
    console.log('Time: ', Date.now()); //获取当前的操作时间 可以取消
    next();
    });

    router.get('/', function(req, res) {
    res.send('Get Data');
    });

    router.get('/:id', function(req, res) {
    //connection.connect();
    var sql = 'SELECT * FROM test_01 where A = '+req.params.id;
    console.log('ID:', req.params.id); //搜索的ID
    connection.query(sql,function (err, result) {
    if(err){
    console.log('[SELECT ERROR] - ',err.message);
    return;
    }
    console.log('--------------------------SELECT----------------------------');
    console.log(result);
    console.log('------------------------------------------------------------\n\n');
    // connection.end();
    res.send(result);
    });
    });

    module.exports = router;



    再新建一个express-mysql.js

    var express = require('express');
    var app = express();
    var mysql = require('mysql');

    var GetDate = require('./getdate');

    var connection = mysql.createConnection({ //配置你本地的数据库
    host : 'localhost',
    user : 'root',
    password : 88888888
    database : 'test'
    });

    connection.connect(); //一直开启连接

    var server = app.listen(3000, function () {
    var host = server.address().address;
    var port = server.address().port;

    console.log('Example app listening at http://%s:%s', host, port);
    });

    app.use('/get',GetDate); //此处是express的中间件,看过express的教程应该很快就懂

    在此处已经算完成了大部分后端的大部分操作了,现在可以访问

    http://localhost:3000/get/1     来查找数据库test_01表中A=1的数据了


    5.实际效果如图所示:

    test_01表



    通过访问http://localhost:3000/get/1  的效果图

    express框架可以主动把放回的数据转化为JSON


    6.接下来就是实现安卓部分的代码了,其实也只要很简单的通过HTTP来访问这个URL就可以实现了

    以下是关键代码

        private void sendRequestWithOkHttp() {   //okhttp  get方式获取服务器数据
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        OkHttpClient client = new OkHttpClient();
                        Request request = new Request.Builder()
                                // 指定访问的服务器地址是电脑本机
                                .url("http://192.168.134.2:3000/get/1")
                              //  .url("http://10.0.2.2/get_data.json")
                                .build();
                        Response response = client.newCall(request).execute();
                        String responseData = response.body().string();
                        parseJSONWithGSON(responseData);
                        showResponse(responseData);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }).start();
        }
    private void showResponse(final String response) {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                // 在这里进行UI操作,将结果显示到界面上
                responseText.setText(response);
            }
        });
    }
    服务器POST的方法大同小异



    展开全文
  • 对于Androidpc的通信,有很多没有写好的东西,也...首先是pc端的服务器(运用ServerSocket去进行交互):import java.io.*; import java.net.*; public class AndroidServer implements Runnable{ public static ...

    对于Android和pc的通信,有很多没有写好的东西,也借鉴了很多大佬写的程序,发出来算是一个集合,有很多不足之处,请各位大佬指点。

    首先是pc端的服务器(运用ServerSocket去进行交互):
    import java.io.*;
    import java.net.*;
    
    
    public class AndroidServer implements Runnable{
    	public static final String SERVERIP = "192.168.1.1";//你本机的ip地址
    	private final int SERVERPORT =8888;
    	private ServerSocket serverSocket;
    	private OutputStream fos;
    	
    	@Override
    	public void run() {
    		try{
    			System.out.println("S:服务器启动!");
    			
    			serverSocket = new ServerSocket(SERVERPORT);
    			while(true) {
    				Socket client = serverSocket.accept();
    				
    				System.out.println("S: Receiving...已连接!ip:" + client.getInetAddress());
    				
    				try{
    					BufferedReader in = new BufferedReader(
    							new InputStreamReader(client.getInputStream(),"utf-8"));
    					
    					PrintWriter out = new PrintWriter(new BufferedWriter(
    							new OutputStreamWriter(client.getOutputStream(),"utf-8")),true);
    					
    					String str = in.readLine();
    					
    						if(str != null){
    							out.println("You sent to server message is:" + str);
    							out.flush();
    							
    							File file = new File("android.txt");
    							fos = new FileOutputStream(file);
    							byte[] b = str.getBytes();
    							for(int i=0;i<b.length;i++){
    								fos.write(b[i]);
    							}
    							System.out.println("S: Received: '" + str + "'");
    							
    						}else{
    							System.out.println("Not receiver anything from client!");
    						}
    					}catch (Exception e){
    						System.out.println("S: Error 1");
    						e.printStackTrace();
    					}finally{
    						client.close();
    						System.out.println("S: 结束.");
    					}
    				}	
    					
    				}catch (Exception e){
    					System.out.println("S: Error 2");
    					e.printStackTrace();
    				}
    						
    	}
    		
    	
    	
    	public static void main(String[] args) {
    		Thread sT = new Thread(new AndroidServer());
    		sT.start();
    
    	}
    }
    
    需要注意的地方就是UTF-8是为了中文不乱码。
    Android端的客户端(socket):
    package com.test.tcpudpsocket;
    
    import java.io.*;
    import java.net.*;
    import android.support.v7.app.ActionBarActivity;
    import android.annotation.SuppressLint;
    import android.os.Bundle;
    import android.os.Handler;
    import android.os.Message;
    import android.util.Log;
    import android.view.Menu;
    import android.view.MenuItem;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.widget.Button;
    import android.widget.EditText;
    import android.widget.TextView;
    
    @SuppressLint("HandlerLeak")
    public class TCPSocket_android extends ActionBarActivity {
    	private static final String TAG = "Socket_Android";
    	
    	private EditText mEditText = null;
    	private TextView tx1 = null;
    	private Button mButton = null;
    	
    	private Handler handler = new Handler(){
    		@Override
    		public void handleMessage(Message msg) {
    			super.handleMessage(msg);
    			if(msg.what == 1){
    				tx1.setText(msg.getData().getString("msg2"));
    			}
    		}
    	};
    	
    	@Override
    	protected void onCreate(Bundle savedInstanceState) {
    		super.onCreate(savedInstanceState);
    		setContentView(R.layout.activity_tcpsocket_android);
    		
    		mButton = (Button)findViewById(R.id.Button1);
    		mEditText = (EditText)findViewById(R.id.etSendMsg);
    		tx1 = (TextView)findViewById(R.id.tx1);
    		
    		mButton.setOnClickListener(new OnClickListener()  {
    			
    			@Override
    			public void onClick(View v){
    				//setTitle("测试TCP连接");
    				setTitle("测试UDP连接");
    				new Thread(net).start();
    			}		
    		} );
    		
    	}
    
    	Runnable net = new Runnable() {
    		//private Socket socket;
    		private DatagramSocket socket;
    		
    		@Override
    		public void run(){	
    			
    			Socket = new Socket();	
    			try{
    				SocketAddress socketAddress = new InetSocketAddress("192.168.1.1",8888);//这里是你本机的ip地址
    				Log.d("TCP", "C: Connection");
    				
    				socket.connect(socketAddress,3000);
    				String msg = "---Test_Socet!---";
    				
    				Log.d("TCP", "C: Sending: '" + msg + "'");
    				
    				PrintWriter out = new PrintWriter(new BufferedWriter(
    						new OutputStreamWriter(socket.getOutputStream(),"utf-8")
    						),true);
    				
    				String toServer = mEditText.getText().toString();
    				Log.d(TAG, "To server:'" + toServer + "'");
    				out.println(toServer);
    				out.flush();
    				
    				BufferedReader in = new BufferedReader(
    						new InputStreamReader(socket.getInputStream(),"utf-8"));
    				
    				String msg2 = in.readLine();
    				Log.d(TAG, "From Server:'" + msg2 + "'");
    				
    				Message message = new Message();
    				Bundle bundle=new Bundle();
    				bundle.putString("msg2", msg2);
    				message.setData(bundle);
    				handler.sendMessage(message);
    				message.what=1;
    				
    			}catch(UnknownHostException e){
    				Log.e(TAG, "192.168.1.128 id unkown server!");
    			}catch(Exception e){
    				e.printStackTrace();
    			}finally{
    				try{
    					System.out.println("服务器关闭");
    					socket.close();
    				}catch(Exception e){
    					e.printStackTrace();
    				}
    			}				
    		}
    	};
    	
    	
    	@Override
    	public boolean onCreateOptionsMenu(Menu menu) {
    		// Inflate the menu; this adds items to the action bar if it is present.
    		getMenuInflater().inflate(R.menu.tcpsocket_android, menu);
    		return true;
    	}
    
    	@Override
    	public boolean onOptionsItemSelected(MenuItem item) {
    		// Handle action bar item clicks here. The action bar will
    		// automatically handle clicks on the Home/Up button, so long
    		// as you specify a parent activity in AndroidManifest.xml.
    		int id = item.getItemId();
    		if (id == R.id.action_settings) {
    			return true;
    		}
    		return super.onOptionsItemSelected(item);
    	}
    }
    

    耗时的线程要在工作线程中运行,所以要创建一个子线程来运行socket的操作。

    用handler 和 message在UI线程和工作线程之间传递信息。

    这是layout的布局:

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:paddingBottom="@dimen/activity_vertical_margin"
        android:paddingLeft="@dimen/activity_horizontal_margin"
        android:paddingRight="@dimen/activity_horizontal_margin"
        android:paddingTop="@dimen/activity_vertical_margin"
        tools:context="com.test.tcpudpsocket.TCPSocket_android" >
        
        <EditText
         	android:id="@+id/etSendMsg"
         	android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:hint="@null"
             />
        
        <Button
            android:id="@+id/Button1"
            android:layout_below="@id/etSendMsg" 
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:text="@string/button1_name"
            />
    	
         <TextView
            android:id="@+id/tx1"
            android:layout_below="@id/Button1" 
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:text="@string/tx1_name"
            />
        
         
        
    </RelativeLayout>
    

    String.xml

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
    
        <string name="app_name">TCP UDP Socket</string>
        <string name="hello_world">Hello world!</string>
        <string name="action_settings">Settings</string>
        <string name="button1_name">发送</string>
        <string name="etSendMsg_msg">etSendMsg</string>
        <string name="tx1_name"></string>
    
    </resources>
    
    这是布局中对应的id属性。

    以上是用socket连接的安卓与pc的交互


    下面写写安卓与pc用udp来交互


    pc端的服务器:

    import java.io.*;
    import java.net.*;
    
    
    public class AndroidServeru implements Runnable{
    	public static final String SERVERIP = "192.168.1.1";//这里写你的ip地址
    	private final int SERVERPORT =8888;//端口号
    	private DatagramSocket socket;
    	private OutputStream fos;
    	
    	@Override
    	public void run() {
    		try{
    			System.out.println("S:UDP服务器启动!");
    			
    			socket = new DatagramSocket(SERVERPORT);
    			while(true) {
    				
    				try{
    					DatagramPacket p = new DatagramPacket(new byte[512],512);
    					socket.receive(p);
    					
    					String msg = new String(p.getData(),0,p.getLength(),"UTF-8");//这里UTF-8是为了不乱码
    					System.out.println("Form" + p.getAddress() + ":" + p.getPort()
    							+ ">" + msg);
    		
    					
    					p.setData(("You sent to server message is:" + msg).getBytes("UTF-8"));
    					socket.send(p);
    							
    					File file = new File("androidu.txt");
    					fos = new FileOutputStream(file);
    					byte[] b = msg.getBytes("UTF-8");//一定要有UTF-8才不会乱码
    					for(int i=0;i<b.length;i++){
    						fos.write(b[i]);
    					}
    							
    							
    					}catch (IOException e){
    						System.out.println("S: Error 1");
    						e.printStackTrace();
    					}
    				}	
    					
    				}catch (Exception e){
    					System.out.println("S: Error 2");
    					e.printStackTrace();
    				}
    						
    	}
    		
    	
    	
    	public static void main(String[] args) {
    		Thread sT = new Thread(new AndroidServeru());
    		sT.start();
    
    	}
    }
    

    Android客户端:


    package com.test.tcpudpsocket;
    
    import java.io.*;
    import java.net.*;
    import android.support.v7.app.ActionBarActivity;
    import android.annotation.SuppressLint;
    import android.os.Bundle;
    import android.os.Handler;
    import android.os.Message;
    import android.util.Log;
    import android.view.Menu;
    import android.view.MenuItem;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.widget.Button;
    import android.widget.EditText;
    import android.widget.TextView;
    
    @SuppressLint("HandlerLeak")
    public class TCPSocket_android extends ActionBarActivity {
    	private static final String TAG = "Socket_Android";
    	
    	private EditText mEditText = null;
    	private TextView tx1 = null;
    	private Button mButton = null;
    	
    	private Handler handler = new Handler(){
    		@Override
    		public void handleMessage(Message msg) {
    			super.handleMessage(msg);
    			if(msg.what == 1){
    				tx1.setText(msg.getData().getString("msg2"));
    			}
    		}
    	};
    	
    	@Override
    	protected void onCreate(Bundle savedInstanceState) {
    		super.onCreate(savedInstanceState);
    		setContentView(R.layout.activity_tcpsocket_android);
    		
    		mButton = (Button)findViewById(R.id.Button1);
    		mEditText = (EditText)findViewById(R.id.etSendMsg);
    		tx1 = (TextView)findViewById(R.id.tx1);
    		
    		mButton.setOnClickListener(new OnClickListener()  {
    			
    			@Override
    			public void onClick(View v){
    				//setTitle("测试TCP连接");
    				setTitle("测试UDP连接");
    				new Thread(net).start();
    			}		
    		} );
    		
    	}
    
    	Runnable net = new Runnable() {
    		//private Socket socket;
    		private DatagramSocket socket;
    		
    		@Override
    		public void run(){				
    			
    			try{
    				socket = new DatagramSocket();
    				InetAddress reIP = InetAddress.getByName("196.168.1.1");//你本机的ip地址
    				
    				Log.d("UDP", "C: Connection");
    				
    				String msg = mEditText.getText().toString();
    					
    				byte[] outputData = msg.getBytes();
    				DatagramPacket outputPacket = new DatagramPacket(outputData,outputData.length,reIP,8888);
    				socket.send(outputPacket);
    				
    				Log.d("UDP", "C: Sending: '" + msg + "'");
    				Log.d(TAG, "To server:'" + msg + "'");
    				
    				DatagramPacket inputPacket = new DatagramPacket(new byte[512],512);
    				socket.receive(inputPacket);
    				
    				final String msg2 = new String(inputPacket.getData(),0,inputPacket.getLength(),"UTF-8");//这里要有UTF-8才不会中文乱码
    				Log.d(TAG, "From Server:'" + msg2 + "'");
    					
    				Message message = new Message();
    				Bundle bundle=new Bundle();
    				bundle.putString("msg2", msg2);
    				message.setData(bundle);
    				handler.sendMessage(message);
    				message.what=1;
    				
    			}catch(UnknownHostException e){
    				Log.e(TAG, "10.16.51.154 id unkown server!");
    			}catch(IOException e){
    				e.printStackTrace();
    			}finally{
    				try{
    					System.out.println("服务器关闭");
    					socket.close();
    				}catch(Exception e){
    					e.printStackTrace();
    				}
    			}
    		}
    	};
    	
    	
    	@Override
    	public boolean onCreateOptionsMenu(Menu menu) {
    		// Inflate the menu; this adds items to the action bar if it is present.
    		getMenuInflater().inflate(R.menu.tcpsocket_android, menu);
    		return true;
    	}
    
    	@Override
    	public boolean onOptionsItemSelected(MenuItem item) {
    		// Handle action bar item clicks here. The action bar will
    		// automatically handle clicks on the Home/Up button, so long
    		// as you specify a parent activity in AndroidManifest.xml.
    		int id = item.getItemId();
    		if (id == R.id.action_settings) {
    			return true;
    		}
    		return super.onOptionsItemSelected(item);
    	}
    }
    

    其他的layout.xml和String.xml都不变。

    值得注意的是AndroidManifest.xml里面要设置一下

     <!--允许应用程序改变网络状态-->  
    	<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>  
    	<!--允许应用程序改变WIFI连接状态-->  
    	<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>  
    	<!--允许应用程序访问有关的网络信息-->  
    	<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>  
    	<!--允许应用程序访问WIFI网卡的网络信息-->  
    	<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>  
    	<!--允许应用程序完全使用网络-->  
    	<uses-permission android:name="android.permission.INTERNET"/>  
    	<uses-permission android:name="android.permission.WAKE_LOCK" />  

    要设置软件可以连接网络。

    因为参考了很多资料,网上就能找到,就不一一写出来了。

    展开全文
  • 通过adb命令,可以很方便的在pc端操作android设备。 adb devices 描述:在执行adb命令前,最好知道连接有多少可用设备连接到adb服务。 您可以使用该命令生成一个已连接的设备列表。 输出的每个实例的格式...

    adb的全称为Android Debug Bridge,就是起到调试桥的作用。通过adb命令,可以很方便的在pc端操作android设备。

    adb devices 

    描述:在执行adb命令最好知道连接有多少可用设备连接到adb服务 可以使用该命令生成一个已连接的设备列表。

    输出的每个实例格式如下:

    [serialNumber] [state] 

    adb打印的每个实例状态信息

    • Serial number — adb通过设备端口号创建的字符串,以其唯一标识设备实例。这个特殊号码的格式为<type>-<consolePort>。
    • State — 实例的连接状态。支持三个状态:
      • offline — 此实例没有与adb相连接或者无法响应.
      • device  — 此实例正与adb服务器连接。注意这个状态并不能百分之百地表示在运行和操作Android系统,因此这个实例是当系统正在运行的时候与adb连接的。然而,在系统启动之后,就是一个模拟器/设备状态的正常运行状态了
    • 如果当前没有模拟器/设备运行,adb则返回 no device .

    如果有多个模拟器/设备实例在运行,在发布adb命令时需要指定一个目标实例。这样做,请使用-s 选项的命令。在使用的-s 选项是

    adb [ -d|-e|-s <serialNumber>] <command>  

    描述:如上所示,给一个命令指定了目标实例,这个目标实例使用由adb分配的序列号。你可以使用 devices 命令来获得运行着的模拟器/设备实例的序列号

    示例如下:

    adb -s emulator-5556 install helloWorld.apk

    注意这点,如果没有指定一个目标模拟器/设备实例就执行 -s 这个命令的话,adb会产生一个错误

    参数信息

    • -s — 指定 device or emulator
    • -d — device
    • -e — emulator
    • serialNumber — 设备唯一标识
    • command — 要执行的命令,比如说:install 123.apk

    从模拟器/设备中拷入或拷出文件

    可以使用adb pull ,push 命令将文件复制到一个模拟器/设备实例的数据文件或是从数据文件中复制。install 命令只将一个.apk文件复制到一个特定的位置,与其不同的是,pull 和 push 命令可令你复制任意的目录和文件到一个模拟器/设备实例的任何位置。

    从模拟器或者设备中复制文件或目录,使用(如下命令):

    adb [-s <serialNumber>] pull <remote> <local>  

    将文件或目录复制到模拟器或者设备,使用(如下命令):

    adb [-s <serialNumber>] push <local> <remote>  

    在这些命令中, <local> <remote> 分别指通向自己的发展机(本地)和模拟器/设备实例(远程)上的目标文件/目录的路径

    下面是一个例子: 

    adb push D:\foo.txt /sdcard/foo.txt

    备注:还可以通过ddms工具,进行文件的导入导出


    安装&卸载软件

    你可以使用adb从你的开发电脑上复制一个应用程序,并且将其安装在一个模拟器/设备实例。像这样做,使用install 命令。这个install 命令要求你必须指定你所要安装的.apk文件的路径:

    adb [-s serialName] install <path_to_apk>

    adb install [-l] [-r] [-s] <file> - push this package file to the device and install it
    ('-l' means forward-lock the app)
    ('-r' means reinstall the app, keeping its data)
    ('-s' means install on SD card instead of internal storage)

    adb uninstall <软件名/包名>
    adb uninstall -k <软件名/包名>

    如果加 -k 参数,为卸载软件但是保留配置和缓存文件.


    ADB Shell命令进入Android端命令窗口后,可以输入shell命令来进行常用操作:

    cd——改变当前目录
    pwd——查看当前所在目录完整路径
    ls——查看目录或者文件的属*,列举出任一目录下面的文件
    mkdir——建立目录
    cp——拷贝文件
    rm——删除文件和目录
    mv——移走目录或者改文件名
    chmod/chown——权限修改
    clear——清屏
    mount——加载一个硬件设备
    su——在不退出登陆的情况下,切换到另外一个人的身份
    grep——文本内容搜索
    find——文件或者目录名以及权限属主等匹配搜索
    kill——可以杀死某个正在进行或者已经是dest状态的进程
    df——命令用来检查文件系统的磁盘空间占用情况



    展开全文
  • Android与Unity交互研究

    2015-07-03 00:28:19
    unity与android交互的由来 unity简单介绍 unity与android交互介绍 unity调用android的方法 android调用untiy的方法unity与android交互的由来本人在项目开发过程中,遇到这样一个需求,把unity的场
  • Android与PC蓝牙交互

    2016-07-21 15:16:36
    Android与PC蓝牙交互 蓝牙( Bluetooth® ):是一种无线技术标准,可实现固定设备、移动设备和楼宇个人域网之间的短距离数据交换 我之所以会来做Android与PC蓝牙通信的了解,是源于公司年会的时候做的抽奖活动,...
  • Android与PC蓝牙交互源代码。最基本的Android与笔记本电脑蓝牙通讯的DEMO
  • 一直以来对Android socket通信都很模糊,今天终于研究了一个网上的例子,自己又修改了下,算是对Android socket通信有点了解了。 下面是具体的代码,说明都在注释中了。需要注意的是,只有客户端发送了信息给服务器...
  • 自己写的一个小Dome,不是项目,主要是使用USB数据线来连接PC端和Android端进行一个数据的交互。一个PC端的客户端类,和Android端的服务端代码。
  • 最近做android开发,需要用户能够在android终端反馈相应信息给后台客服,后台使用PC界面。主要的功能如下:  1、在联网能够相互通信的情况下,终端将信息上传到服务器  2、在联网互相通信的下,服务器端客服如果...
  • Android客户端与PC服务器通过socket进行交互
  • 对于其他的客户端,他们经常无能为力,如果PC端采用jsp或者其他视图框架来渲染页面,后台开发人员就得对相同的请求处理两次(一次数据传给PC端用,一次数据返回给其他客户端用(Android、IOS、M站)),这样就显得...
  • (1)PC端(2)Android端接下来,我们看一下实现。(1)Android端(2)PC端吐槽适配器适配器的性能也是参差不齐。此前摁着绿联的蓝牙适配器,试了3天。同样的代码,问题百出。后来转用奥视通(ost108),几分钟便过...
  • 实现了Android客户端服务器的交互,客户端采用Android Studio开发,Web服务器采用MyEclipse开发,数据库使用MySQL,采用Hibernate框架开发
  • Ø 数据库整理方案如下: 一、Android+ webservices+SQLServer : 通过webservices客户端向指定服务器发送请求,服务器响应返回指定格式的数据,如json或者xml格式。 (数据库操作在服务器端完成...Android做客户端,PC
  • Android与Js交互,知道的有两种方法 WebView webView=findViewById(R.id.webView); WebSettings settings =webView.getSetting(); mWebView.loadUrl("网页url"); 一、通过WebClient监听URL来拦截 1、 ...
  • 之前看了很多关于Unity与Android通信与交互的帖子,但是在做的过程当中遇到很多坑的地方,最终呢还是做出来了,所以就顺便记下,同时也希望能帮助到需要的小伙伴。 首先我们创建一个Android工程: 下面红框的...
  • 公司有这样一个需求,一个萤火虫的开发板子,不要图形化界面,并且将公司的算法集成到板子中,由PC端传递数据到板子中进行数据的操作将结果返回给PC端,要使用USB来进行连接。这里的使用USB连接不是指,将手机当成一...
  • Android通过USB与PC通信

    2013-12-12 09:07:57
    最近项目中有一个功能需要用到Android与PC端同步数据。查阅了相关资料后,采取了一种建立在adb基础之上的Usb通信方式:由于adb可以将Usb模拟为网卡,所以可以利用socket通信的方式实现Android与PC机的通信,以完成...
1 2 3 4 5 ... 20
收藏数 20,789
精华内容 8,315
热门标签