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

下載本文檔

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

文檔簡介

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

2、機的sokcet,一定要用adb forward來作下端口轉(zhuǎn)發(fā)才能連 上 socket.view plaincopy to cli pboard print?Run time.getR un time().exec(adb forward tcp :12580 tcp :10086);Thread.slee p(3000);Run time.getR un time().exec(adb forward tcp :12580 tcp :10086);Thread.slee p(3000);4.a ndroid端的service程序In stall到手機上容易,但是還要有方法來從PC的clie

3、nt端來啟動手機上的 service,這個辦法可以通過 PC端adb命令來發(fā)一個 Broastcast,手機 端再寫個接收 BroastcastReceive來接收這個 Broastcast,在這個 BroastcastReceive來啟動 servicepc端命令:view plaincopy to cli pboard print?Run time.getR un time().exec(adb shell am broadcast -a NotifyServiceStart);Run time.getR un time().exec(adb shell am broadcast -a N

4、otifyServiceStart);an droid 端的代碼:ServiceBroadcastReceiver.javaview plaincopy to cli pboard print? p ackage com.otheri.service;import an droid.c onten t.BroadcastReceiver;import an droid.c onten t.C on text;import an droid.c onten t.I ntent;import an droid.util.Log;p ublic class ServiceBroadcastRecei

5、ver exte nds BroadcastReceiver private static Stri ng START_ACTION = NotifyServiceStart; private static Stri ng STOP_ACTION = NotifyServiceSto p;Overridep ublic void on Receive(C on text con text, Intent intent) Log.d(androidService.TAG , Thread.currentThread().getName() + + ServiceBroadcastReceiver

6、 on Receive);String action = inten t.getAct ion();if (START_ACTION.equalslg noreCase(actio n) con text.startService (new Inten t(c on text, an droidService.class);Log.d(androidService.TAG , Thread.currentThread().getName() + + ServiceBroadcastReceiver on Receive start en d); else if (STOP_ACTION.equ

7、alsIg noreCase(actio n) con text.st op Service (new Inten t(c on text, an droidService.class);Log.d(androidService.TAG , Thread.currentThread().getName() + + ServiceBroadcastReceiver on Receive stop en d);p ackage com.otheri.service;import an droid.c onten t.BroadcastReceiver;import an droid.c onten

8、 t.C on text;import an droid.c onten t.I ntent;import an droid.util.Log;p ublic class ServiceBroadcastReceiver exte nds BroadcastReceiver private static Stri ng START_ACTION = NotifyServiceStart; private static Stri ng STOP_ACTION = NotifyServiceSto p;Overridep ublic void on Receive(C on text con te

9、xt, Intent intent) Log.d(androidService.TAG , Thread.currentThread().getName() + -+ ServiceBroadcastReceiver on Receive);String action = inten t.getAct ion();if (START_ACTION.equalsIg noreCase(actio n) con text.startService (new Inten t(c on text, an droidService.class);Log.d(androidService.TAG , Th

10、read.currentThread().getName() + + ServiceBroadcastReceiver on Receive start en d); else if (STOP_ACTION.equalsIg noreCase(actio n) con text.st op Service (new Inten t(c on text, an droidService.class);Log.d(androidService.TAG , Thread.currentThread().getName() + + ServiceBroadcastReceiver on Receiv

11、e stop en d);USB連接,所以socket就可以設(shè)計為一但連接就一直聯(lián)通,即在new socket和5.由于是開完out,in流后,就用個while(true)來循環(huán)PC端和an droid端的讀和寫an droid的代碼: view plaincopy to cli pboard print?p ublic void run() Log.d(androidService.TAG , Thread.currentThread().getName() + + a die nt has conn ected to server!);BufferedOut pu tStream out;

12、BufferedI npu tStream in;try /* PC端發(fā)來的數(shù)據(jù)msg */Stri ng currCMD =;out = new BufferedOut pu tStream(clie nt.getOut pu tStream();in = new BufferedI npu tStream(clie nt.get Inpu tStream(); / testSocketO;/ 測試 socket 方法 an droidService.ioThreadFlag = true;while (an droidService.ioThreadFlag) try if (!clie

13、nt.isCo nn ected() break; /*接收PC發(fā)來的數(shù)據(jù)*/Log.v(androidService.TAG , Thread.currentThread().getName()+ - + will read.);/*讀操作命令*/currCMD = readCMDFromSocket(i n);Log.v(androidService.TAG , Thread.currentThread().getName()+ - + *currCMD = + currCMD);*/*根據(jù)命令分別處理數(shù)據(jù)if (currCMD.equals(1) out.write(OK.getByte

14、s(); out.flush(); else if (currCMD.equals(2) out.write(OK.getBytes(); out.flush(); else if (currCMD.equals(3) out.write(OK.getBytes(); out.flush(); else if (currCMD.equals(4) /*準備接收文件數(shù)據(jù)*/try out.write(service receive OK.getBytes();out.flush(); catch (IOExce ptio n e) e.prin tStackTrace();/*接收文件數(shù)據(jù),4字

15、節(jié)文件長度,4字節(jié)文件格式,其后是文件數(shù)據(jù)*/byte filele ngth = new byte4;byte fileformat = new byte4;byte filebytes = n ull;/*從socket流中讀取完整文件數(shù)據(jù)*/filebytes = receiveFileFromSocket( in, out, filele ngth,fileformat);/ Log.v(Service139.TAG , receive data = + new / Stri ng(filebytes);try /*生成文件*/File file = FileHel per.n ewF

16、ile(R0013340.J PG);FileHelper.writeFile(file, filebytes, 0,filebytes .len gth); catch (IOExce ptio n e) e.prin tStackTrace(); else if (currCMD.equals(exit) catch (Exce pti on e) / try / out.write(error.getBytes(utf-8);/ out.flush();/ catch (IOExce ption e1) / e1. prin tStackTrace();/ Log.e(androidSe

17、rvice.TAG , Thread.currentThread().getName()+ - + read write error111111);out.close();in .close(); catch (Exce pti on e) Log.e(androidService.TAG , Thread.currentThread().getName()+ - + read write error222222);e.prin tStackTrace(); fin ally try if (clie nt != n ull) Log.v(androidService.TAG , Thread

18、.currentThread().getName()+ - + clie nt.closeO);clie nt.closeO; catch (lOExce ptio n e) Log.e(a ndroidService.TAG, Thread.curre ntThread().getName()+ - + read write error333333);e.prin tStackTrace();p ublic void run() Log.d(androidService.TAG , Thread.currentThread().getName() + + a clie nt has conn

19、 ected to server!);BufferedOut pu tStream out;BufferedI np utStream in;try /* PC端發(fā)來的數(shù)據(jù)msg */Stri ng currCMD =;out = new BufferedOut pu tStream(clie nt.getOut pu tStream();in = new BufferedI np utStream(clie nt.getl np utStream(); / testSocketO;/ 測試 socket 方法 an droidService.ioThreadFlag = true;while

20、 (an droidService.ioThreadFlag) try if (!clie nt.isCo nn ected() break; /*接收PC發(fā)來的數(shù)據(jù)*/Log.v(androidService.TAG , Thread.currentThread().getName()+ - + will read.);/*讀操作命令*/currCMD = readCMDFromSocket(i n);Log.v(androidService.TAG , Thread.currentThread().getName()+ - + *currCMD = + currCMD);*/*根據(jù)命令分別

21、處理數(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(4) /*準備接收文件數(shù)據(jù)*/try out.write(service receive OK.getBytes();out.flush(); catch (IOE

22、xce ptio n e) e.prin tStackTrace();/*接收文件數(shù)據(jù),4字節(jié)文件長度,4字節(jié)文件格式,其后是文件數(shù)據(jù)*/byte filele ngth = new byte4;byte fileformat = new byte4;byte filebytes = n ull;/*從socket流中讀取完整文件數(shù)據(jù)*/filebytes = receiveFileFromSocket( in, out, filele ngth.fileformat);/ Log.v(Service139.TAG , receive data = + new/ Stri ng(filebyt

23、es); try /*生成文件*/File file = FileHel per.n ewFile(R0013340.J PG);FileHel per.writeFile(file, filebytes, 0, filebytes .len gth); catch (IOExce ptio n e) e.prin tStackTrace(); else if (currCMD.equals(exit) catch (Exce pti on e) / try / out.write(error.getBytes(utf-8);/ out.flush();/ catch (IOExce ptio

24、n e1) / e1.prin tStackTrace();/ Log.e(androidService.TAG , Thread.currentThread().getName()+ - + read write error111111);out.close();in .close(); catch (Exce pti on e) Log.e(androidService.TAG , Thread.currentThread().getName()+ - + read write error222222);e.prin tStackTrace(); fin ally try if (clie

25、 nt != n ull) Log.v(androidService.TAG , Thread.currentThread().getName()+ - + clie nt.closeO);clie nt.closeO; catch (IOExce ptio n e) Log.e(a ndroidService.TAG, Thread.curre ntThread().getName()+ - + read write error333333);e.prin tStackTrace();6.如果是在PC端和an droid端的讀寫操作來 while(true)循環(huán),這樣socket流的結(jié)尾不好

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

27、h:流的前4個字節(jié)存儲要轉(zhuǎn)送的文件的字節(jié)數(shù)* byte fileformat :流的前5-8字節(jié)存儲要轉(zhuǎn)送的文件的格式(如.apk)* */p ublic static byte receiveFileFromSocket(l npu tStream in,Out putStream out, byte filele ngth, byte fileformat) byte filebytes = n ull;/文件數(shù)據(jù)try int filelen = MyUtil.bytesTolnt(filelength);/文件長度從 4 字節(jié) byte轉(zhuǎn)成 IntString strt mp = re

28、ad file len gth ok: + filele n; out.write(strt mp .getBytes(utf-8); out.flush();filebytes = new bytefilele n;int pos = 0;int rcvLe n = 0;while (rcvLe n = in. read(filebytes, pos, filele n - po s) 0) pos += rcvLe n;Log.v(androidService.TAG , Thread.currentThread().getName()+ - + read file OK:file siz

29、e= + filebytes.le ngth);out.write(read file ok.getBytes(utf-8); out.flush(); catch (Exce pti on e) Log.v(androidService.TAG , Thread.currentThread().getName()+ - + receiveFileFromSocket error); e.prin tStackTrace();retur n filebytes;/*功能:從socket流中讀取完整文件數(shù)據(jù)* InputStream in : socket 輸入流* byte filelengt

30、h:流的前4個字節(jié)存儲要轉(zhuǎn)送的文件的字節(jié)數(shù)* byte fileformat :流的前5-8字節(jié)存儲要轉(zhuǎn)送的文件的格式(如.apk)* */p ublic static byte receiveFileFromSocket(I npu tStream in,Out putStream out, byte filele ngth, byte fileformat) byte filebytes = n ull;/文件數(shù)據(jù)try int filelen = MyUtil.bytesTolnt(filelength);/文件長度從 4 字節(jié) byte轉(zhuǎn)成 IntStri ng strtmp = re

31、ad file len gth ok: + filele n; out.write(strt mp .getBytes(utf-8); out.flush();filebytes = new bytefilele n;int pos = 0;int rcvLe n = 0;while (rcvLe n = in. read(filebytes, pos, filele n - po s) 0) pos += rcvLe n;Log.v(a ndroidService.TAG, Thread.curre ntThread().getName()+ - + read file OK:file si

32、ze= + filebytes.le ngth);out.write(read file ok.getBytes(utf-8);out.flush(); catch (Exce pti on e) Log.v(androidService.TAG , Thread.currentThread().getName()+ - + receiveFileFromSocket error);e.prin tStackTrace();return filebytes;8.socket的最重要的機制就是讀寫采用的是阻塞的方式,如果客戶端作為命令發(fā)起者,服 務(wù)器端作為接收者的話,只有當客戶端client用o

33、ut.writer()寫到輸出流里后,即流中有數(shù)據(jù)service的read才會執(zhí)行,不然就會一直停在read()那里等數(shù)據(jù)。9.還要讓服務(wù)器端可以同時連接多個client,即服務(wù)器端用 new thread()來作數(shù)據(jù)讀取操作。源碼:客戶端(pc端):test PcClie nt.java view plaincopy to cli pboard print? import java.io.BufferedI npu tStream; import java.io.BufferedOut pu tStream;import java.io.BufferedReader;import java.

34、io.ByteArrayOut pu tStream;import java.i o.I OExce pti on;import java.i o.Inpu tStream;import java.i o.Inpu tStreamReader;import java .n et.I netAddress;import java .n et.Socket;import java .n et. UnknownH ostExce pti on;p ublic class test PcClie nt * p aram args* throws Interrup tedExce ptio n*/p u

35、blic static void main( Stri ng args) throws Interrup tedExce ptio n try Run time.getR un time().exec(adb shell am broadcast -a NotifyServiceSt op ”);Thread.slee p(3000);Run time.getRu ntime().exec(adb forward tcp:12580 tcp:10086);Thread.slee p(3000);Run time.getR un time().exec(adb shell am broadcas

36、t -a NotifyServiceStart);Thread.slee p(3000); catch (IOExce ption e3) e3.prin tStackTrace();Socket socket = n ull;try In etAddress serverAddr = n ull;serverAddr = In etAddress.getByName(127.0.0.1);System.out .prin tl n( TC P 1111 + C: Co nn ecti ng.); socket = new Socket(serverAddr, 12580);String st

37、r = hi,wufe nglon g;System.out .prin tl n( TC P 221122 + C:RECEIVE);BufferedOut pu tStream out = new BufferedOut pu tStream(socket.getOut putStream();Bufferedl np utStream in = new Bufferedl np utStream(socket.getl npu tStream();BufferedReader br = new BufferedReader( new Inp utStreamReader(System.i

38、 n);boolea n flag = true;while (flag) System.out.print(請輸入16的數(shù)字,退出輸入exit: ”);String strWord = br.readLine();/ 從控制臺輸入 16 if (strWord.equals(1) out.write(1.getBytes();out.flush();System.out. printin (1 finish sending the data); string strFormsocket = readFromSocket(i n);System.out. println (the data s

39、ent by server is:r n+ strFormsocket);System.out.println (=”); else if (strWord.equals(2) out.write(2.getBytes(); out.flush();System.out. println (2 finish sending the data);String strFormsocket = readFromSocket(i n);System.out. println (the data sent by server is:r n+ strFormsocket);System.out.print

40、ln (=”); else if (strWord.equals(3) out.write(3.getBytes(); out.flush();System.out. println (3 finish sending the data);String strFormsocket = readFromSocket(i n);System.out. println (the data sent by server is:r n+ strFormsocket);System.out.println (=); else if (strWord.equals(4) /*發(fā)送命令*/out.write(

41、4.getBytes();out.flush();System.out .println( se nd file fi nish sen di ng the CMD :);/*服務(wù)器反饋:準備接收*/Stri ng strFormsocket = readFromSocket(i n);System.out.println( service ready receice data:U PDATE_CONTACTS:+ strFormsocket);byte filebytes = FileHel per.readFile(R0013340.J PG);System.out. prin tl n(

42、file size= + filebytes .len gth);/*將整數(shù)轉(zhuǎn)成4字節(jié)byte數(shù)組*/byte filele ngth = new byte4;filele ngth = tools.i ntToByte(filebytes .len gth);/*將.apk字符串轉(zhuǎn)成4字節(jié)byte數(shù)組*/byte fileformat = n ull;fileformat = .a pk.getBytes();System.out.println (fileformat le ngth= + fileformat.le ngth);/*字節(jié)流中前4字節(jié)為文件長度,4字節(jié)文件格式,以后是文件流

43、*/*注意如果write里的byte超過socket的緩存,系統(tǒng)自動分包寫過*/去,所以對方要循環(huán)寫完out.write(filele ngth);out.flush();Stri ng strok1 = readFromSocket(i n);System.out. println (service receive filele ngth : + strok1);/ out.write(fileformat);/ out.flush();/ Stri ng strok2 = readFromSocket( in);/ System.out .println (service receive

44、fileformat : +/ strok2);System.out. println (write data to an droid); out.write(filebytes);out.flush();System.out. println(*);/*服務(wù)器反饋:接收成功*/String strread = readFromSocket(i n);System.out. println (” send data success: + strread);System.out.println (”); else if (strWord.equalsIg noreCase(EXIT) out.w

45、rite(EXIT.getBytes();out.flush();System.out. println (EXIT finish sending the data);String strFormsocket = readFromSocket(i n);System.out. println (the data sent by server is:r n+ strFormsocket);flag = false;System.out.println (=”); catch (UnknownH ostExce pti on e1) System.out. println (TC P 331133

46、 + ERROR: + e1.toStri ng(); catch (Exce pti on e2) System.out. println (TC P 441144 + ERROR: + e2.toStri ng(); fin ally try if (socket != n ull) socket.close();System.out. println (socket.close(); catch (lOExce ptio n e) System.out. prin tl n( TC P 5555 + ERROR: + e.toStri ng();I*從InputStream流中讀數(shù)據(jù) *

47、/p ublic static String readFromSocket(l npu tStream in) int MAX_BUFFER_BYTES = 4000;Stri ng msg =;byte te mp buffer = new byteMAX_BUFFER_BYTES;try int nu mReadedBytes = in. read(te mp buffer, 0, temp bufferen gth);msg = new Strin g(te mp buffer, 0, nu mReadedBytes, utf-8);temp buffer = nu II; catch

48、(Exce pti on e) e.prin tStackTrace();/ Log.v(Service139.TAG, msg= + msg); return msg;import java.io.Bufferedl npu tStream;import java.io.BufferedOut pu tStream;import java.io.BufferedReader;import java.io.ByteArrayOut pu tStream;import java.i o.l OExce pti on;import java.i o.Inpu tStream;import java

49、.i o.Inpu tStreamReader;import java .n et.I netAddress;import java .n et.Socket;import java .n et. UnknownH ostExce pti on;p ublic class test PcClie nt /* p aram args* throws Interrup tedExce ptio n*/p ublic static void main( Stri ng args) throws Interrup tedExce ptio n try Run time.getR un time().e

50、xec(adb shell am broadcast -a NotifyServiceSt op ”);Thread.slee p(3000);Run time.getRu ntime().exec(adb forward tcp:12580 tcp:10086);Thread.slee p(3000);Run time.getR un time().exec(adb shell am broadcast -a NotifyServiceStart);Thread.slee p(3000); catch (IOExce ption e3) e3.prin tStackTrace();Socke

51、t socket = n ull;try In etAddress serverAddr = n ull;serverAddr = In etAddress.getByName(127.0.0.1); System.out .prin tl n( TC P 1111 + C: Conn ecti ng.); socket = new Socket(serverAddr, 12580);String str = hi,wufe nglon g;System.out. printin (TC P 221122 + C:RECEIVE);BufferedOut pu tStream out = ne

52、w BufferedOut pu tStream(socket.getOut putStream();Bufferedl np utStream in = new Bufferedl npu tStream(socket.getl npu tStream();BufferedReader br = new BufferedReader( new Inp utStreamReader(System.i n);boolea n flag = true;while (flag) System.out.print(請輸入16的數(shù)字,退出輸入exit:);String strWord = br.read

53、Line();/ 從控制臺輸入 16 if (strWord.equals(1) out.write(1.getBytes();out.flush();System.out. println (1 finish sending the data); Stri ng strFormsocket = readFromSocket(i n);System.out. println (the data sent by server is:r n+ strFormsocket);System.outprintin (” else if (strWord.equals(2) out.write(2.getBytes(); out.flush();System.out. println (2 finish sending the data); Stri ng strFormsocket = readFromSocket(i n);Syste

溫馨提示

  • 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)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論