


版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、PC 客户端与 Android 服务端的 Socket 同步通信( USB) 收藏 需求:1. 一个 android 端的 service 后台运行的程序, 作为 socket 的服务器端 ;用于接收 Pc client 端发来的命令,来处理数据后,把结果发给 PC client2. PC 端程序,作为 socket 的客户端,用于给 android 手机端发操作命令难点分析:1手机一定要有adb模式,即插上 USB线时马上提示的对话框选adb。好多对手机的操作都可以用 adb 直接作。不过,我发现 LG GW880 就没有,要去下载个2. android 默认手机端的 IP 为“127.0.
2、0.1”3. 要想联通PC与an droid手机的sokcet, 定要用adb forward来作下端口转发才能连 上 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 命令来发一个 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 就可以设计为一但连接就一直联通,即在new socket 和开完 out,in 流后,就用个 while(true) 来循环 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 端发来的数据 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 发来的数据 */Log.v(androidService.TAG , Thread.currentThread().getN
14、ame()+ ">" + "will read");/* 读操作命令 */ currCMD = readCMDFromSocket(in);Log.v(androidService.TAG , Thread.currentThread().getName()+ ">" + "*currCMD = " + currCMD);/* 根据命令分别处理数据 */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") /* 准备接收文件数据 */ try out.write("service receive OK".getBytes(); out
16、.flush(); catch (IOException e) e.printStackTrace();件数据 */* 接收文件数据, 4字节文件长度, 4 字节文件格式,其后是文byte filelength = new byte4; byte fileformat = new byte4; byte filebytes = null;/* 从 socket 流中读取完整文件数据 */ 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 端发来的数据 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 发来的数据 */Log.v(androidService.TAG , Thread.currentThread().getName() + ">" + "will read");/* 读操作命令 */ currCMD = readCMDFromSocket(in); Log.v(androidService.TAG, Thread.currentThread().getName()+ ">" + "*currCMD = " + currCMD);/* 根
23、据命令分别处理数据 */ 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") /* 准备接收文件数据 */ try out.write("service receive OK".getBytes(); out.flush(); catch (IOException e) e.printStackTrace();件数据 */* 接收文件数据, 4字节文件长度, 4 字节文件格式,其后是文byte filelength = new byte4; byte fileformat = new byte4; byte filebytes = null;/* 从 socket 流中读取完整文件数据 */ 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) 循环, 这样 socket 流的结尾不好 判断,不能用 “-1”来判断,因为 “-1”是只有在 sock
29、et 关闭时才作为判断结尾。7. socket 在 out.write(bytes); 时,要是数据太大时,超过 socket 的缓存, socket 自动分包发 送,所以对方就一定要用循环来多次读。 最好的办法就是服务器和客户端协议好, 比如发文 件时,先写过来一个要发送的文件的大小,然后再发送文件;对方用这个大小,来循环读取数据。android 端接收数据的代码view plaincopy to clipboardprint?/* 功能:从 socket 流中读取完整文件数据* InputStream in : socket 输入流* byte filelength: 流的前 4 个字节存
30、储要转送的文件的字节数*.apk)* byte fileformat :流的前 5-8 字节存储要转送的文件的格式(如public static byte receiveFileFromSocket(InputStream in,OutputStream out, byte filelength, byte fileformat) byte filebytes = null;/ 文件数据 try int filelen = MyUtil.bytesToInt(filelength);/ 文件长度从 4 字节 byte 转成 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 流中读取完整文件数据* InputStream in : socket 输入流* byte filelength: 流的前 4 个字节存储要转送的文件的字节数*.apk)* byte fileformat :流的前 5-8 字节存储要转送的文件的格式(如*public static byte receiveFileFromSocket(InputStream in, OutputStream out, byte filelength, byte fileformat) byte filebytes = null;/ 文件数据try int fil
34、elen = MyUtil.bytesToInt(filelength);/ 文件长度从 4 字节 byte 转成 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 的最重要的机制就是读写采用的是阻塞的方式,如果客户端作为命令发起者,服 务器端作为接收者的话,只有当客户端 client 用 out.writer() 写到输出流里后,即流中有数据 service的read才会执行,不然就会一直停在read()那里等数据。源码:客户端( 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 的数字 ,退出输入 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;) /* 发送命令 */out.write("4".getBytes();out.flush();System.out.println("send file finish sending the CMD : ");/* 服务器反馈:准备接收 */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);/* 将整数转成 4 字节 byte 数组 */byte filelength = new byte4;filelength = ToByte(filebytes.length);/*将.apk字符串转成4字节byte数组*/byte fileformat = null; fileformat = ".apk".getBytes();System.
47、out.println("fileformat length=" + fileformat.length);/* 字节流中前 4 字节为文件长度, 4 字节文件格式, 以后是文件流 */ /* 注意如果 write 里的 byte 超过 socket 的缓存,系统自动分包写过 去,所以对方要循环写完 */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("*");/* 服务器反馈:接收成功 */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 流中读数据 */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 的数字 ,退出输入 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") /* 发送命令 */ out.write("4".getBytes(); out.flush();S
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 功能性吸水树脂工程融资投资立项项目可行性研究报告(齐鲁咨询)
- 儿科护理工作方案模板
- 幼儿园班级环境创设计划方案
- 2025年中国锻制接管座行业市场发展前景及发展趋势与投资战略研究报告
- 加固项目工程方案计划施工组织方案计划(方案计划)
- 河南省中招一模数学试卷
- 中医医院建设项目环境影响报告书
- 中国重力分级去石机行业市场发展前景及发展趋势与投资战略研究报告(2024-2030)
- 河北单招九类数学试卷
- 河南师大二模数学试卷
- 酒店客房房价促销方案范文
- 药厂环保知识培训课件
- DB3301T 0378-2022 城市照明质量评价规范
- 【指导规则】央企控股上市公司ESG专项报告参考指标体系
- 《慢性乙型肝炎防治指南(2022年版)-》解读
- 制造业数字化生产与质量管理方案设计
- 部编版初中语文7-9年级教材必背古诗词、古文99篇详细解析及欣赏
- 划线及交通设施工程施工方案
- 知识产权尽职调查报告
- 电子病历信息安全管理制度
- 北师大版小学数学六年级上册第一单元圆《欣赏与设计》公开课 教学课件
评论
0/150
提交评论