PC客户端与Android服务端的Socket同步通信USB.docx
- 文档编号:30299253
- 上传时间:2023-08-13
- 格式:DOCX
- 页数:34
- 大小:28.59KB
PC客户端与Android服务端的Socket同步通信USB.docx
《PC客户端与Android服务端的Socket同步通信USB.docx》由会员分享,可在线阅读,更多相关《PC客户端与Android服务端的Socket同步通信USB.docx(34页珍藏版)》请在冰豆网上搜索。
PC客户端与Android服务端的Socket同步通信USB
PC客户端与Android服务端的Socket同步通信(USB)
需求:
1.一个android端的service后台运行的程序,作为socket的服务器端;用于接收Pcclient端发来的命令,来处理数据后,把结果发给PCclient
2.PC端程序,作为socket的客户端,用于给android手机端发操作命令
难点分析:
1.手机一定要有adb模式,即插上USB线时马上提示的对话框选adb。
好多对手机的操作都可以用adb直接作。
不过,我发现LGGW880就没有,要去下载个
2.android默认手机端的IP为“127.0.0.1”
3.要想联通PC与android手机的sokcet,一定要用adbforward来作下端口转发才能连上socket.
[java]viewplaincopy
1Runtime.getRuntime().exec("adbforwardtcp:
12580tcp:
10086");
2Thread.sleep(3000);
4.android端的service程序Install到手机上容易,但是还要有方法来从PC的client端来启动手机上的service,这个办法可以通过PC端adb命令来发一个Broastcast,手机端再写个接收BroastcastReceive来接收这个Broastcast,在这个BroastcastReceive来启动service
pc端命令:
[java]viewplaincopy
3Runtime.getRuntime().exec(
4"adbshellambroadcast-aNotifyServiceStart");
android端的代码:
ServiceBroadcastReceiver.java
[java]viewplaincopy
5packagecom.otheri.service;
6
7importandroid.content.BroadcastReceiver;
8importandroid.content.Context;
9importandroid.content.Intent;
10importandroid.util.Log;
11
12publicclassServiceBroadcastReceiverextendsBroadcastReceiver{
13privatestaticStringSTART_ACTION="NotifyServiceStart";
14privatestaticStringSTOP_ACTION="NotifyServiceStop";
15
16@Override
17publicvoidonReceive(Contextcontext,Intentintent){
18Log.d(androidService.TAG,Thread.currentThread().getName()+"---->"
19+"ServiceBroadcastReceiveronReceive");
20
21Stringaction=intent.getAction();
22if(START_ACTION.equalsIgnoreCase(action)){
23context.startService(newIntent(context,androidService.class));
24
25Log.d(androidService.TAG,Thread.currentThread().getName()+"---->"
26+"ServiceBroadcastReceiveronReceivestartend");
27}elseif(STOP_ACTION.equalsIgnoreCase(action)){
28context.stopService(newIntent(context,androidService.class));
29Log.d(androidService.TAG,Thread.currentThread().getName()+"---->"
30+"ServiceBroadcastReceiveronReceivestopend");
31}
32}
33
34}
5.由于是USB连接,所以socket就可以设计为一但连接就一直联通,即在newsocket和开完out,in流后,就用个while(true){}来循环PC端和android端的读和写
android的代码:
[java]viewplaincopy
35publicvoidrun(){
36Log.d(androidService.TAG,Thread.currentThread().getName()+"---->"
37+"aclienthasconnectedtoserver!
");
38BufferedOutputStreamout;
39BufferedInputStreamin;
40try{
41/*PC端发来的数据msg*/
42StringcurrCMD="";
43out=newBufferedOutputStream(client.getOutputStream());
44in=newBufferedInputStream(client.getInputStream());
45//testSocket();//测试socket方法
46androidService.ioThreadFlag=true;
47while(androidService.ioThreadFlag){
48try{
49if(!
client.isConnected()){
50break;
51}
52
53/*接收PC发来的数据*/
54Log.v(androidService.TAG,Thread.currentThread().getName()
55+"---->"+"willread......");
56/*读操作命令*/
57currCMD=readCMDFromSocket(in);
58Log.v(androidService.TAG,Thread.currentThread().getName()
59+"---->"+"**currCMD===="+currCMD);
60
61/*根据命令分别处理数据*/
62if(currCMD.equals("1")){
63out.write("OK".getBytes());
64out.flush();
65}elseif(currCMD.equals("2")){
66out.write("OK".getBytes());
67out.flush();
68}elseif(currCMD.equals("3")){
69out.write("OK".getBytes());
70out.flush();
71}elseif(currCMD.equals("4")){
72/*准备接收文件数据*/
73try{
74out.write("servicereceiveOK".getBytes());
75out.flush();
76}catch(IOExceptione){
77e.printStackTrace();
78}
79
80/*接收文件数据,4字节文件长度,4字节文件格式,其后是文件数据*/
81byte[]filelength=newbyte[4];
82byte[]fileformat=newbyte[4];
83byte[]filebytes=null;
84
85/*从socket流中读取完整文件数据*/
86filebytes=receiveFileFromSocket(in,out,filelength,
87fileformat);
88
89//Log.v(Service139.TAG,"receivedata="+new
90//String(filebytes));
91try{
92/*生成文件*/
93Filefile=FileHelper.newFile("R0013340.JPG");
94FileHelper.writeFile(file,filebytes,0,
95filebytes.length);
96}catch(IOExceptione){
97e.printStackTrace();
98}
99}elseif(currCMD.equals("exit")){
100
101}
102}catch(Exceptione){
103//try{
104//out.write("error".getBytes("utf-8"));
105//out.flush();
106//}catch(IOExceptione1){
107//e1.printStackTrace();
108//}
109Log.e(androidService.TAG,Thread.currentThread().getName()
110+"---->"+"readwriteerror111111");
111}
112}
113out.close();
114in.close();
115}catch(Exceptione){
116Log.e(androidService.TAG,Thread.currentThread().getName()
117+"---->"+"readwriteerror222222");
118e.printStackTrace();
119}finally{
120try{
121if(client!
=null){
122Log.v(androidService.TAG,Thread.currentThread().getName()
123+"---->"+"client.close()");
124client.close();
125}
126}catch(IOExceptione){
127Log.e(androidService.TAG,Thread.currentThread().getName()
128+"---->"+"readwriteerror333333");
129e.printStackTrace();
130}
131}
6.如果是在PC端和android端的读写操作来while(true){}循环,这样socket流的结尾不好判断,不能用“-1”来判断,因为“-1”是只有在socket关闭时才作为判断结尾。
7.socket在out.write(bytes);时,要是数据太大时,超过socket的缓存,socket自动分包发送,所以对方就一定要用循环来多次读。
最好的办法就是服务器和客户端协议好,比如发文件时,先写过来一个要发送的文件的大小,然后再发送文件;对方用这个大小,来循环读取数据。
android端接收数据的代码:
[java]viewplaincopy
132/**
133*功能:
从socket流中读取完整文件数据
134*
135*InputStreamin:
socket输入流
136*
137*byte[]filelength:
流的前4个字节存储要转送的文件的字节数
138*
139*byte[]fileformat:
流的前5-8字节存储要转送的文件的格式(如.apk)
140*
141**/
142publicstaticbyte[]receiveFileFromSocket(InputStreamin,
143OutputStreamout,byte[]filelength,byte[]fileformat){
144byte[]filebytes=null;//文件数据
145try{
146intfilelen=MyUtil.bytesToInt(filelength);//文件长度从4字节byte[]转成Int
147Stringstrtmp="readfilelengthok:
"+filelen;
148out.write(strtmp.getBytes("utf-8"));
149out.flush();
150
151filebytes=newbyte[filelen];
152intpos=0;
153intrcvLen=0;
154while((rcvLen=in.read(filebytes,pos,filelen-pos))>0){
155pos+=rcvLen;
156}
157Log.v(androidService.TAG,Thread.currentThread().getName()
158+"---->"+"readfileOK:
filesize="+filebytes.length);
159out.write("readfileok".getBytes("utf-8"));
160out.flush();
161}catch(Exceptione){
162Log.v(androidService.TAG,Thread.currentThread().getName()
163+"---->"+"receiveFileFromSocketerror");
164e.printStackTrace();
165}
166returnfilebytes;
167}
8.socket的最重要的机制就是读写采用的是阻塞的方式,如果客户端作为命令发起者,服务器端作为接收者的话,只有当客户端client用out.writer()写到输出流里后,即流中有数据service的read才会执行,不然就会一直停在read()那里等数据。
9.还要让服务器端可以同时连接多个client,即服务器端用newthread()来作数据读取操作。
源码:
客户端(pc端):
testPcClient.java
[java]viewplaincopy
168importjava.io.BufferedInputStream;
169importjava.io.BufferedOutputStream;
170importjava.io.BufferedReader;
171importjava.io.ByteArrayOutputStream;
172importjava.io.IOException;
173importjava.io.InputStream;
174importjava.io.InputStreamReader;
175import.InetAddress;
176import.Socket;
177import.UnknownHostException;
178
179publicclasstestPcClient{
180
181/**
182*@paramargs
183*@throwsInterruptedException
184*/
185publicstaticvoidmain(String[]args)throwsInterruptedException{
186try{
187Runtime.getRuntime().exec(
188"adbshellambroadcast-aNotifyServiceStop");
189Thread.sleep(3000);
190Runtime.getRuntime().exec("adbforwardtcp:
12580tcp:
10086");
191Thread.sleep(3000);
192Runtime.getRuntime().exec(
193"adbshellambroadcast-aNotifyServiceStart");
194Thread.sleep(3000);
195}catch(IOExceptione3){
196e3.printStackTrace();
197}
198
199Socketsocket=null;
200try{
201InetAddressserverAddr=null;
202serverAddr=InetAddress.getByName("127.0.0.1");
203System.out.println("TCP1111"+"C:
Connecting...");
204socket=newSocket(serverAddr,12580);
205Stringstr="hi,wufenglong";
206System.out.println("TCP221122"+"C:
RECEIVE");
207BufferedOutputStreamout=newBufferedOutputStream(socket
208.getOutputStream());
209BufferedInputStreamin=newBufferedInputStream(socket
210.getInputStream());
211BufferedReaderbr=newBufferedReader(newInputStreamReader(
212System.in));
213booleanflag=true;
214while(flag){
215System.out.print("请输入1~6的数字,退出输入exit:
");
216StringstrWord=br.readLine();//从控制台输入1~6
217if(strWord.equals("1")){
218out.write("1".getBytes());
219out.flush();
220System.out.println("1finishsendingthedata");
221StringstrFormsocket=readFromSocket(in);
222System.out.println("thedatasentbyserveris:
/r/n"
223+strFormsocket);
224System.out
225.println("=============================================");
226}elseif(strWord.equals("2")){
227out.write("2".getBytes());
228out.flush();
229System.out.println("2finishsendingthedata");
230StringstrFormsocket=readFromSocket(in);
231System.out.println("thedatasentbyserveris:
/r/n"
232+strFormsocket);
233System.out
234.println("=============================================");
235}elseif(strWord.equals("3")){
236out.write("3".getBytes());
237out.flush();
238System.out.println("3finishsendingthedata");
239StringstrFormsocket=readFromSocket(in);
240System.out.println("thedatasentbyserveris:
/r/n"
241+strFormsocket);
242System.out
243.println("=============================================");
244}elseif(strWord.equals("4")){
245/*发送命令*/
246out.write("4".getBytes());
247out.flush();
248System.out.
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- PC 客户端 Android 服务端 Socket 同步 通信 USB