PC客戶端與A服務(wù)端的S同步通信_第1頁
PC客戶端與A服務(wù)端的S同步通信_第2頁
PC客戶端與A服務(wù)端的S同步通信_第3頁
已閱讀5頁,還剩32頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

1、PC 客戶端與 Android 服務(wù)端的 Socket 同步通信( USB) 收藏 需求:1. 一個 android 端的 service 后臺運行的程序, 作為 socket 的服務(wù)器端 ;用于接收 Pc client 端發(fā)來的命令,來處理數(shù)據(jù)后,把結(jié)果發(fā)給 PC client2. PC 端程序,作為 socket 的客戶端,用于給 android 手機端發(fā)操作命令難點分析:1手機一定要有adb模式,即插上 USB線時馬上提示的對話框選adb。好多對手機的操作都可以用 adb 直接作。不過,我發(fā)現(xiàn) LG GW880 就沒有,要去下載個2. android 默認手機端的 IP 為“127.0.

2、0.1”3. 要想聯(lián)通PC與an droid手機的sokcet, 定要用adb forward來作下端口轉(zhuǎn)發(fā)才能連 上 socket.view plaincopy to clipboardprint?Runtime.getRuntime().exec("adb forward tcp:12580 tcp:10086");Thread.sleep(3000);Runtime.getRuntime().exec("adb forward tcp:12580 tcp:10086");Thread.sleep(3000);4. android 端的 servic

3、e 程序 Install 到手機上容易,但是還要有方法來從 PC 的 client 端來啟動手機上的 service ,這個辦法可以通過 PC 端 adb 命令來發(fā)一個 Broastcast ,手機 端再寫個接收 BroastcastReceive來接收這個 Broastcast,在這個 BroastcastReceive來啟動servicepc 端命令:view plaincopy to clipboardprint?Runtime.getRuntime().exec("adb shell am broadcast -a NotifyServiceStart");Runt

4、ime.getRuntime().exec("adb shell am broadcast -a NotifyServiceStart");android 端的代碼 :ServiceBroadcastReceiver.javaview plaincopy to clipboardprint?package com.otheri.service;import android.content.BroadcastReceiver;import android.content.Context;import android.content.Intent;import android.

5、util.Log;public class ServiceBroadcastReceiver extends BroadcastReceiver private static String START_ACTION = "NotifyServiceStart" private static String STOP_ACTION = "NotifyServiceStop"Overridepublic void onReceive(Context context, Intent intent) Log.d(androidService.TAG , Threa

6、d.currentThread().getName() + ">"+ "ServiceBroadcastReceiver onReceive");String action = intent.getAction();if (START_ACTION.equalsIgnoreCase(action) context.startService(new Intent(context, androidService.class);Log.d(androidService.TAG , Thread.currentThread().getName() + &q

7、uot;>"+ "ServiceBroadcastReceiver onReceive start end"); else if (STOP_ACTION.equalsIgnoreCase(action) context.stopService(new Intent(context, androidService.class); Log.d(androidService.TAG , Thread.currentThread().getName() + ">"+ "ServiceBroadcastReceiver onRec

8、eive stop end");package com.otheri.service;import android.content.BroadcastReceiver;import android.content.Context;import android.content.Intent;import android.util.Log;public class ServiceBroadcastReceiver extends BroadcastReceiver private static String START_ACTION = "NotifyServiceStart&

9、quot; private static String STOP_ACTION = "NotifyServiceStop"Overridepublic void onReceive(Context context, Intent intent) Log.d(androidService.TAG , Thread.currentThread().getName() + ">"+ "ServiceBroadcastReceiver onReceive");String action = intent.getAction();if (

10、START_ACTION.equalsIgnoreCase(action) context.startService(new Intent(context, androidService.class);Log.d(androidService.TAG , Thread.currentThread().getName() + ">"+ "ServiceBroadcastReceiver onReceive start end"); else if (STOP_ACTION.equalsIgnoreCase(action) context.stopSe

11、rvice(new Intent(context, androidService.class); Log.d(androidService.TAG , Thread.currentThread().getName() + ">"+ "ServiceBroadcastReceiver onReceive stop end");5. 由于是 USB 連接,所以 socket 就可以設(shè)計為一但連接就一直聯(lián)通,即在new socket 和開完 out,in 流后,就用個 while(true) 來循環(huán) PC 端和 android 端的讀和寫android

12、的代碼:view plaincopy to clipboardprint?public void run() Log.d(androidService.TAG , Thread.currentThread().getName() + ">"+ "a client has connected to server!");BufferedOutputStream out;BufferedInputStream in;try /* PC 端發(fā)來的數(shù)據(jù) msg */String currCMD = ""out = new Buffered

13、OutputStream(client.getOutputStream();in = new BufferedInputStream(client.getInputStream();/ testSocket();/ 測試 socket 方法 androidService.ioThreadFlag = true; while (androidService.ioThreadFlag) try if (!client.isConnected() break;/* 接收 PC 發(fā)來的數(shù)據(jù) */Log.v(androidService.TAG , Thread.currentThread().getN

14、ame()+ ">" + "will read");/* 讀操作命令 */ currCMD = readCMDFromSocket(in);Log.v(androidService.TAG , Thread.currentThread().getName()+ ">" + "*currCMD = " + currCMD);/* 根據(jù)命令分別處理數(shù)據(jù) */if (currCMD.equals("1") out.write("OK".getBytes(); out.f

15、lush(); else if (currCMD.equals("2") out.write("OK".getBytes(); out.flush(); else if (currCMD.equals("3") out.write("OK".getBytes(); out.flush(); else if (currCMD.equals("4") /* 準備接收文件數(shù)據(jù) */ try out.write("service receive OK".getBytes(); out

16、.flush(); catch (IOException e) e.printStackTrace();件數(shù)據(jù) */* 接收文件數(shù)據(jù), 4字節(jié)文件長度, 4 字節(jié)文件格式,其后是文byte filelength = new byte4; byte fileformat = new byte4; byte filebytes = null;/* 從 socket 流中讀取完整文件數(shù)據(jù) */ filebytes = receiveFileFromSocket(in, out, filelength, fileformat);/ Log.v(Service139.TAG , "receiv

17、e data =" + new/ String(filebytes);try /* 生成文件 */File file = FileHelper.newFile("R0013340.JPG"); FileHelper.writeFile(file, filebytes, 0, filebytes.length); catch (IOException e) e.printStackTrace(); else if (currCMD.equals("exit") catch (Exception e) / try / out.write("

18、;error".getBytes("utf-8");/ out.flush();/ catch (IOException e1) / e1.printStackTrace();/ Log.e(androidService.TAG , Thread.currentThread().getName() + ">" + "read write error111111"); out.close(); in.close(); catch (Exception e) Log.e(androidService.TAG , Threa

19、d.currentThread().getName()+ ">" + "read write error222222");e.printStackTrace(); finally try if (client != null) Log.v(androidService.TAG , Thread.currentThread().getName() + ">" + "client.close()");client.close(); catch (IOException e) Log.e(androidSer

20、vice.TAG, Thread.currentThread().getName() + ">" + "read write error333333");e.printStackTrace(); public void run() Log.d(androidService.TAG , Thread.currentThread().getName() + ">"+ "a client has connected to server!");BufferedOutputStream out;BufferedI

21、nputStream in;try /* PC 端發(fā)來的數(shù)據(jù) msg */ String currCMD = "" out = new BufferedOutputStream(client.getOutputStream(); in = new BufferedInputStream(client.getInputStream();/ testSocket();/ 測試 socket 方法 androidService.ioThreadFlag = true; while (androidService.ioThreadFlag) try if (!client.isCo

22、nnected() break;/* 接收 PC 發(fā)來的數(shù)據(jù) */Log.v(androidService.TAG , Thread.currentThread().getName() + ">" + "will read");/* 讀操作命令 */ currCMD = readCMDFromSocket(in); Log.v(androidService.TAG, Thread.currentThread().getName()+ ">" + "*currCMD = " + currCMD);/* 根

23、據(jù)命令分別處理數(shù)據(jù) */ if (currCMD.equals("1") out.write("OK".getBytes(); out.flush(); else if (currCMD.equals("2") out.write("OK".getBytes(); out.flush(); else if (currCMD.equals("3") out.write("OK".getBytes(); out.flush(); else if (currCMD.equals(&

24、quot;4") /* 準備接收文件數(shù)據(jù) */ try out.write("service receive OK".getBytes(); out.flush(); catch (IOException e) e.printStackTrace();件數(shù)據(jù) */* 接收文件數(shù)據(jù), 4字節(jié)文件長度, 4 字節(jié)文件格式,其后是文byte filelength = new byte4; byte fileformat = new byte4; byte filebytes = null;/* 從 socket 流中讀取完整文件數(shù)據(jù) */ filebytes = rec

25、eiveFileFromSocket(in, out, filelength, fileformat);/ Log.v(Service139.TAG , "receive data =" + new/ String(filebytes);try /* 生成文件 */File file = FileHelper.newFile("R0013340.JPG");FileHelper.writeFile(file, filebytes, 0,filebytes.length); catch (IOException e) e.printStackTrace()

26、; else if (currCMD.equals("exit") catch (Exception e) / try / out.write("error".getBytes("utf-8");/ out.flush();/ catch (IOException e1) / e1.printStackTrace();/ Log.e(androidService.TAG , Thread.currentThread().getName() + ">" + "read write error11111

27、1"); out.close(); in.close(); catch (Exception e) Log.e(androidService.TAG , Thread.currentThread().getName() + ">" + "read write error222222");e.printStackTrace(); finally try if (client != null) Log.v(androidService.TAG , Thread.currentThread().getName()+ ">&quo

28、t; + "client.close()");client.close(); catch (IOException e) Log.e(androidService.TAG, Thread.currentThread().getName()+ ">" + "read write error333333");e.printStackTrace();6. 如果是在 PC 端和 android 端的讀寫操作來 while(true) 循環(huán), 這樣 socket 流的結(jié)尾不好 判斷,不能用 “-1”來判斷,因為 “-1”是只有在 sock

29、et 關(guān)閉時才作為判斷結(jié)尾。7. socket 在 out.write(bytes); 時,要是數(shù)據(jù)太大時,超過 socket 的緩存, socket 自動分包發(fā) 送,所以對方就一定要用循環(huán)來多次讀。 最好的辦法就是服務(wù)器和客戶端協(xié)議好, 比如發(fā)文 件時,先寫過來一個要發(fā)送的文件的大小,然后再發(fā)送文件;對方用這個大小,來循環(huán)讀取數(shù)據(jù)。android 端接收數(shù)據(jù)的代碼view plaincopy to clipboardprint?/* 功能:從 socket 流中讀取完整文件數(shù)據(jù)* InputStream in : socket 輸入流* byte filelength: 流的前 4 個字節(jié)存

30、儲要轉(zhuǎn)送的文件的字節(jié)數(shù)*.apk)* byte fileformat :流的前 5-8 字節(jié)存儲要轉(zhuǎn)送的文件的格式(如public static byte receiveFileFromSocket(InputStream in,OutputStream out, byte filelength, byte fileformat) byte filebytes = null;/ 文件數(shù)據(jù) try int filelen = MyUtil.bytesToInt(filelength);/ 文件長度從 4 字節(jié) byte 轉(zhuǎn)成 Int String strtmp = "read file

31、 length ok:" + filelen; out.write(strtmp.getBytes("utf-8");out.flush();filebytes = new bytefilelen;int pos = 0;int rcvLen = 0;while (rcvLen = in.read(filebytes, pos, filelen - pos) > 0) pos += rcvLen;Log.v(androidService.TAG , Thread.currentThread().getName() + ">" + &

32、quot;read file OK:file size=" + filebytes.length);out.write("read file ok".getBytes("utf-8"); out.flush(); catch (Exception e) Log.v(androidService.TAG, Thread.currentThread().getName()+ ">" + "receiveFileFromSocket error");e.printStackTrace(); return

33、filebytes;* 功能:從 socket 流中讀取完整文件數(shù)據(jù)* InputStream in : socket 輸入流* byte filelength: 流的前 4 個字節(jié)存儲要轉(zhuǎn)送的文件的字節(jié)數(shù)*.apk)* byte fileformat :流的前 5-8 字節(jié)存儲要轉(zhuǎn)送的文件的格式(如*public static byte receiveFileFromSocket(InputStream in, OutputStream out, byte filelength, byte fileformat) byte filebytes = null;/ 文件數(shù)據(jù)try int fil

34、elen = MyUtil.bytesToInt(filelength);/ 文件長度從 4 字節(jié) byte 轉(zhuǎn)成 Int String strtmp = "read file length ok:" + filelen; out.write(strtmp.getBytes("utf-8");out.flush();filebytes = new bytefilelen;int pos = 0;int rcvLen = 0;while (rcvLen = in.read(filebytes, pos, filelen - pos) > 0) pos

35、 += rcvLen;Log.v(androidService.TAG , Thread.currentThread().getName() + ">" + "read file OK:file size=" + filebytes.length);out.write("read file ok".getBytes("utf-8"); out.flush(); catch (Exception e) Log.v(androidService.TAG , Thread.currentThread().getNa

36、me()+ ">" + "receiveFileFromSocket error");e.printStackTrace();return filebytes;8. socket 的最重要的機制就是讀寫采用的是阻塞的方式,如果客戶端作為命令發(fā)起者,服 務(wù)器端作為接收者的話,只有當客戶端 client 用 out.writer() 寫到輸出流里后,即流中有數(shù)據(jù) service的read才會執(zhí)行,不然就會一直停在read()那里等數(shù)據(jù)。源碼:客戶端( pc 端):testPcClient.javaview plaincopy to clipboardp

37、rint?import java.io.BufferedInputStream;import java.io.BufferedOutputStream;import java.io.BufferedReader;import java.io.ByteArrayOutputStream;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import .InetAddress;import .Socket;import .UnknownHostException;public

38、 class testPcClient /* param args* throws InterruptedException*/public static void main(String args) throws InterruptedException try Runtime.getRuntime().exec("adb shell am broadcast -a NotifyServiceStop"); Thread.sleep(3000);Runtime.getRuntime().exec("adb forward tcp:12580 tcp:10086&

39、quot;); Thread.sleep(3000);Runtime.getRuntime().exec("adb shell am broadcast -a NotifyServiceStart"); Thread.sleep(3000); catch (IOException e3) e3.printStackTrace();Socket socket = null;try InetAddress serverAddr = null;serverAddr = InetAddress.getByName("");System.out.

40、println("TCP 1111" + "C: Connecting."); socket = new Socket(serverAddr, 12580);String str = "hi,wufenglong"System.out.println("TCP 221122" + "C:RECEIVE"); BufferedOutputStream out = new BufferedOutputStream(socket .getOutputStream();BufferedInputStre

41、am in = new BufferedInputStream(socket .getInputStream();BufferedReader br = new BufferedReader(new InputStreamReader( System.in);boolean flag = true;while (flag) System.out.print(" 請輸入 16 的數(shù)字 ,退出輸入 exit :"); String strWord = br.readLine();/ 從控制臺輸入 16 if (strWord.equals("1") out.

42、write("1".getBytes();out.flush();System.out.println("1 finish sending the data"); String strFormsocket = readFromSocket(in); System.out.println("the data sent by server is:rn"+ strFormsocket);System.out .println("= "); else if (strWord.equals("2") ou

43、t.write("2".getBytes(); out.flush();System.out.println("2 finish sending the data"); String strFormsocket = readFromSocket(in); System.out.println("the data sent by server is:rn"+ strFormsocket);System.out .println("= "); else if (strWord.equals("3")

44、 out.write("3".getBytes(); out.flush();System.out.println("3 finish sending the data"); String strFormsocket = readFromSocket(in); System.out.println("the data sent by server is:rn" + strFormsocket);System.out .println("= ="); else if (strWord.equals("4&q

45、uot;) /* 發(fā)送命令 */out.write("4".getBytes();out.flush();System.out.println("send file finish sending the CMD : ");/* 服務(wù)器反饋:準備接收 */String strFormsocket = readFromSocket(in);System.out.println("service ready receice data:UPDATE_CONTACTS:" + strFormsocket);byte filebytes = Fi

46、leHelper.readFile("R0013340.JPG");System.out.println("file size=" + filebytes.length);/* 將整數(shù)轉(zhuǎn)成 4 字節(jié) byte 數(shù)組 */byte filelength = new byte4;filelength = ToByte(filebytes.length);/*將.apk字符串轉(zhuǎn)成4字節(jié)byte數(shù)組*/byte fileformat = null; fileformat = ".apk".getBytes();System.

47、out.println("fileformat length=" + fileformat.length);/* 字節(jié)流中前 4 字節(jié)為文件長度, 4 字節(jié)文件格式, 以后是文件流 */ /* 注意如果 write 里的 byte 超過 socket 的緩存,系統(tǒng)自動分包寫過 去,所以對方要循環(huán)寫完 */out.write(filelength);out.flush();String strok1 = readFromSocket(in);System.out.println("service receive filelength :" + strok1

48、);/ out.write(fileformat);/ out.flush();/ String strok2 = readFromSocket(in);/ System.out.println("service receive fileformat :" +/ strok2);System.out.println("write data to android"); out.write(filebytes);out.flush();System.out.println("*");/* 服務(wù)器反饋:接收成功 */String strre

49、ad = readFromSocket(in);System.out.println(" send data success:" + strread);System.out.println(""); else if (strWord.equalsIgnoreCase("EXIT") out.write("EXIT".getBytes(); out.flush();System.out.println("EXIT finish sending the data"); String strForms

50、ocket = readFromSocket(in); System.out.println("the data sent by server is:rn" + strFormsocket);flag = false;System.out .println("= ="); catch (UnknownHostException e1) System.out.println("TCP 331133" + "ERROR:" + e1.toString(); catch (Exception e2) System.out

51、.println("TCP 441144" + "ERROR:" + e2.toString(); finally try if (socket != null) socket.close(); System.out.println("socket.close()"); catch (IOException e) System.out.println("TCP 5555" + "ERROR:" + e.toString(); /* 從 InputStream 流中讀數(shù)據(jù) */public sta

52、tic String readFromSocket(InputStream in) int MAX_BUFFER_BYTES = 4000;String msg = ""byte tempbuffer = new byteMAX_BUFFER_BYTES;try int numReadedBytes = in.read(tempbuffer, 0, tempbuffer.length); msg = new String(tempbuffer, 0, numReadedBytes, "utf-8");tempbuffer = null; catch (E

53、xception e) e.printStackTrace();/ Log.v(Service139.TAG, "msg=" + msg); return msg;import java.io.BufferedInputStream;import java.io.BufferedOutputStream;import java.io.BufferedReader;import java.io.ByteArrayOutputStream;import java.io.IOException;import java.io.InputStream;import java.io.I

54、nputStreamReader;import .InetAddress;import .Socket;import .UnknownHostException;public class testPcClient /* param args* throws InterruptedException*/public static void main(String args) throws InterruptedException try Runtime.getRuntime().exec("adb shell am broadcast -a NotifyServiceStop"

55、;);Thread.sleep(3000);Runtime.getRuntime().exec("adb forward tcp:12580 tcp:10086");Thread.sleep(3000);Runtime.getRuntime().exec("adb shell am broadcast -a NotifyServiceStart");Thread.sleep(3000); catch (IOException e3) e3.printStackTrace();Socket socket = null;try InetAddress ser

56、verAddr = null;serverAddr = InetAddress.getByName("");System.out.println("TCP 1111" + "C: Connecting."); socket = new Socket(serverAddr, 12580);String str = "hi,wufenglong"System.out.println("TCP 221122" + "C:RECEIVE");BufferedOutp

57、utStream out = new BufferedOutputStream(socket .getOutputStream();BufferedInputStream in = new BufferedInputStream(socket .getInputStream();BufferedReader br = new BufferedReader(new InputStreamReader( System.in);boolean flag = true;while (flag) System.out.print(" 請輸入 16 的數(shù)字 ,退出輸入 exit :")

58、;String strWord = br.readLine();/ 從控制臺輸入 16if (strWord.equals("1") out.write("1".getBytes(); out.flush();System.out.println("1 finish sending the data"); String strFormsocket = readFromSocket(in); System.out.println("the data sent by server is:rn" + strFormsoc

59、ket);System.out.println("="); else if (strWord.equals("2") out.write("2".getBytes(); out.flush();System.out.println("2 finish sending the data"); String strFormsocket = readFromSocket(in); System.out.println("the data sent by server is:rn" + strForms

60、ocket);System.out.println("="); else if (strWord.equals("3") out.write("3".getBytes(); out.flush();System.out.println("3 finish sending the data"); String strFormsocket = readFromSocket(in); System.out.println("the data sent by server is:rn" + strFormsocket);System.out.println("="); else if (strWord.equals("4") /* 發(fā)送命令 */ out.write("4".getBytes(); out.flush();S

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論