java基于Socket做一个简单下载器
本文实例为大家分享了java基于Socket制作下载器的过程,及相关代码,供大家参考,具体内容如下
1.首先要建立一个服务器用来处理信息并给客户端传输文件(电脑)
我是用电脑开了一个WIFI,手机连上后使用scoket传输的
SERVERIP要根据自己实际情况更改。端口也可以随便更改0~65535,尽量选大一点
importjava.io.BufferedInputStream; importjava.io.BufferedOutputStream; importjava.io.BufferedReader; importjava.io.BufferedWriter; importjava.io.File; importjava.io.FileInputStream; importjava.io.InputStreamReader; importjava.io.OutputStreamWriter; importjava.io.PrintWriter; importjava.net.ServerSocket; importjava.net.Socket; /** *测试Android客户端与PC服务器通过socket进行交互服务器端:接收客户端的信息并回送给客户 * *@authorAmeyume * */ publicclassServerimplementsRunnable{ //定义传输的IP和端口信息 publicstaticfinalStringSERVERIP="192.168.155.1"; //定义的9888端口 publicstaticfinalintSERVERPORT=9888; //定义文件 privateFilefile=null; publicstaticvoidmain(String[]args){ //建立调用线程执行传输的方法 ThreaddesktopServerThread=newThread(newServer()); desktopServerThread.start(); } publicvoidrun(){ try{ System.out.println("S:Connecting...9888"); //创建套接字 ServerSocketserverSocket=newServerSocket(SERVERPORT); while(true){ //等待接受客户端请求 Socketclient=serverSocket.accept(); System.out.println("S:Receiving...9888"); try{ //接受客户端信息 BufferedReaderin=newBufferedReader( newInputStreamReader(client.getInputStream())); System.out.println("S:接收客户端信息"); //读取客户端的信息 Stringstr=in.readLine(); Stringstr1=str.substring(0,2); Stringstr2=str.substring(2); System.out.println(str); //根据客户端的请求找到对应的文件并把文件大小的值传过去 if(str.equals("file_size")){ //定义你要传输的文件(我这里写的是E盘下的某个文件) file=newFile("E:\\某个文件"); //输入流 FileInputStreamfis=newFileInputStream(file); //输出流 BufferedInputStreambis=newBufferedInputStream(fis); //计算将要传输的文件大小 intsum=bis.available(); //将int型的文件大小转成字符串 Strings=String.valueOf(sum); System.out.println(s); //建立输出流以发送文件大小的信息 PrintWriterout=newPrintWriter(newBufferedWriter( newOutputStreamWriter(client.getOutputStream())), true); //发送文件的大小信息 out.println(s); //关闭流 out.flush(); bis.close(); }elseif(str1.equals("ok")){ inta=Integer.parseInt(str2); //客户端收到文件大小的值后,再根据客户端传来的“ok”将文件传过去 BufferedOutputStreambos=newBufferedOutputStream( client.getOutputStream()); System.out.println("S:开始传输"); //开始传输 if(true){ //输入流 FileInputStreamfis=newFileInputStream(file); //跳过前面已经传输过的字节 fis.skip(a); //缓冲输入流 BufferedInputStreambis=newBufferedInputStream( fis); intt=-1; while((t=bis.read())>=0){ bos.write(t); } Strings="已传输"; //关闭流 bos.flush(); bis.close(); bos.close(); //serverSocket.close(); System.out.println("S:Received:'"+s+"'"); } }else{ System.out .println("Notreceiveranythingfromclient!"); } }catch(Exceptione){ System.out.println("S:Error1"); e.printStackTrace(); }finally{ client.close(); System.out.println("S:Done."); } } }catch(Exceptione){ System.out.println("S:Error2"); e.printStackTrace(); } } }
2.再建立一个客户端,我这里用的是安卓写的MainActivity.java(我是在手机上运行的)
packagecom.xhy.zz; importandroid.app.Activity; importandroid.content.Intent; importandroid.os.Bundle; importandroid.os.Handler; importandroid.os.Message; importandroid.view.View; importandroid.view.View.OnClickListener; importandroid.widget.Button; importandroid.widget.TextView; publicclassMainActivityextendsActivity{ //定义Handler publicstaticHandlermyHandler; //定义intent privateIntentintent; //获取控件 privateTextViewtext_name; privateTextViewtext_percent; privateButtonbtn_start; privateButtonbtn_stop; //文件显示 privateTextViewtext_sel_file; @Override protectedvoidonCreate(BundlesavedInstanceState){ //TODOAuto-generatedmethodstub super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); text_name=(TextView)findViewById(R.id.text_name); text_percent=(TextView)findViewById(R.id.text_percent); btn_start=(Button)findViewById(R.id.btn_start); btn_stop=(Button)findViewById(R.id.btn_stop); //按钮一的返回信息,显示进度 myHandler=newHandler(){ @Override publicvoidhandleMessage(Messagemsg){ super.handleMessage(msg); if(msg.what==0x0001){ Bundledata=msg.getData(); Stringstr=data.getString("value"); text_percent.setText(str); } } }; //显式的方式调用HelloService intent=newIntent(this,DownService.class); //设置启动按钮点击事件 btn_start.setOnClickListener(newOnClickListener(){ @Override publicvoidonClick(Viewv){ //开启服务 startService(intent); } }); //设置停止按钮点击事件 btn_stop.setOnClickListener(newOnClickListener(){ @Override publicvoidonClick(Viewv){ //关闭服务 stopService(intent); } }); } /*** *被调用Activity一旦返回值该回调方法将被系统自动调用 */ @Override protectedvoidonActivityResult(intrequestCode,intresultCode, Intentintent){ super.onActivityResult(requestCode,resultCode,intent); //如果请求码是0 //并且返回的结果码为1 //请求的Activity可能返回多种结果码 if(requestCode==0&&resultCode==1){ //取出数据 Bundledata=intent.getExtras(); Stringstr=data.getString("files"); //显示数据 text_sel_file.setText(str); } } }
3.activity_main.xml文件
<?xmlversion="1.0"encoding="utf-8"?> <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="20dp" android:orientation="horizontal"> <TextView android:id="@+id/text_name" android:layout_width="160dp" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:text="1"/> <TextView android:id="@+id/text_percent" android:layout_width="50dp" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:layout_marginLeft="20dp" android:text="0%"/> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="20dp" android:orientation="vertical"> <Button android:id="@+id/btn_start" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="start" /> <Button android:id="@+id/btn_stop" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="stop" /> </LinearLayout> </LinearLayout> </LinearLayout>
4.DownService用于在后台开启线程执行下载
packagecom.xhy.zz; importjava.io.BufferedInputStream; importjava.io.BufferedReader; importjava.io.BufferedWriter; importjava.io.File; importjava.io.FileOutputStream; importjava.io.InputStreamReader; importjava.io.OutputStreamWriter; importjava.io.PrintWriter; importjava.net.InetAddress; importjava.net.Socket; importjava.net.UnknownHostException; importandroid.app.Service; importandroid.content.Context; importandroid.content.Intent; importandroid.content.SharedPreferences; importandroid.os.Bundle; importandroid.os.Environment; importandroid.os.IBinder; importandroid.os.Message; importandroid.util.Log; publicclassDownServiceextendsService{ privatestaticfinalStringTAG="Socket_Android"; //Preferece机制操作的文件名 publicstaticfinalStringPREFERENCE_NAME="DownService"; //Preferece机制的操作模式 publicstaticintMODE=Context.MODE_PRIVATE; //线程 privateThreadworkThread; //定义文件名 privateStringfilename="file"; //端口号 privateintport=9888; privatebooleanisStop=false; /*** *必须要实现的方法 */ @Override publicIBinderonBind(Intentintent){ returnnull; } @Override publicvoidonCreate(){ super.onCreate(); } @Override publicintonStartCommand(Intentintent,intflags,intstartId){ Log.v("TCP",filename); //建立传输的方法 RunnablebackgroundWork=newRunnable(){ @Override publicvoidrun(){ //setTitle("测试Socket连接"); Socketsocket=null; Socketsocket1=null; try{ /* *指定Server的IP地址,此地址为局域网地址,如果是使用WIFI上网,则为PC机的WIFIIP地址 *在ipconfig查看到的IP地址如下:Ethernetadapter无线网络连接: *Connection-specificDNSSuffix.:IPAddress.... *........:192.168.155.1 */ InetAddressserverAddr=InetAddress .getByName("192.168.155.1");//TCPServer.SERVERIP Log.d("TCP","C:Connecting..."); Log.d("TCP",filename+""+port); //应用Server的IP和端口建立Socket对象,向服务端发送请求获取文件大小的值 socket1=newSocket(serverAddr,port); Stringmessage="---Test_Socket_Android---"; Log.d("TCP","C:Sending:'"+message+"'"); //将信息通过这个对象来发送给Server PrintWriterout=newPrintWriter(newBufferedWriter( newOutputStreamWriter( socket1.getOutputStream())),true); //把用户输入的内容发送给server out.println("file_size"); out.flush(); //接收服务器信息 BufferedReaderin=newBufferedReader( newInputStreamReader(socket1.getInputStream())); //获取文件大小 Stringstr1=in.readLine(); Log.d("TCP",str1); //将文件大小转成int型 intsum=Integer.parseInt(str1); Log.d("TCP",str1); //关闭输入流 in.close(); SharedPreferencessharedPreferences=getSharedPreferences( PREFERENCE_NAME,MODE); SharedPreferences.Editoreditor=sharedPreferences .edit(); //取出已经传输了的字节 intpre=sharedPreferences.getInt("DownService",0); int_pre=pre; //将其转化为字符串以便发送给服务端 Strings=String.valueOf(_pre); //应用Server的IP和端口建立Socket对象再次向服务端发送请求,以获取文件内容 socket=newSocket(serverAddr,port); //向服务端发送请求获得文件的字符 PrintWriterout1=newPrintWriter( newBufferedWriter(newOutputStreamWriter( socket.getOutputStream())),true); out1.println("ok"+s); out1.flush(); out.close(); //定义输入流 BufferedInputStreambis=newBufferedInputStream( socket.getInputStream()); Stringfile1=filename; Stringfile; //判断手机是否插入了SDCard,是则将文件插入内存卡 if(Environment.getExternalStorageState().equals( Environment.MEDIA_MOUNTED)){ FilesdCard=Environment .getExternalStorageDirectory(); //SD卡定义文件 file=sdCard.getCanonicalFile()+"/"+file1; //定义文件输出流 FileOutputStreamfos=newFileOutputStream(file,true); try{ intt=-1; intdownloaded=pre; //定义每次传输的字节数 byte[]buff=newbyte[8192]; Log.i("sum",sum+""); //开始将服务端的文件写入手机SD卡中 while((t=bis.read(buff))!=-1){ if(isStop==true){ break; } fos.write(buff,0,t); downloaded+=t; //将传输的进度存储起来 editor.putInt("DownService",downloaded); editor.commit(); //当传完了则把存储信息归零 if(downloaded==sum){ editor.putInt("DownService",0); editor.commit(); } //获得文件传输的进度 floatwb=((downloaded*100)/(float)sum); intwi=(int)wb; System.out.println(downloaded); Stringstr=String.valueOf(wi)+"%"; //将文件的传输进度给送给BaseActivity,以显示给用户 Messagemsg=newMessage();//生成消息 //生成消息 msg.what=0x0001;//设置消息类型 //生成Bundle携带数据 Bundledata=newBundle(); data.putString("value",str); msg.setData(data); //利用Handler发送消息 MainActivity.myHandler.sendMessage(msg); } //关闭输入输出流 bis.close(); fos.flush(); fos.close(); }catch(Exceptione){ bis.close(); fos.flush(); fos.close(); } } Log.d(TAG,"Fromserver:'已接收"+"'"); }catch(UnknownHostExceptione){ Log.e(TAG,"192.168.155.1isunkownserver!"); }catch(Exceptione){ e.printStackTrace(); }finally{ try{ socket.close(); }catch(Exceptione){ e.printStackTrace(); } } } }; workThread=newThread(backgroundWork); //isAlive方法用于判断workThread线程是否被开启 if(!workThread.isAlive()){ //生成新线程 workThread.start(); Log.v("ServiceLife","线程开始工作"); }else{ Log.v("workThread","线程已经被调用"); } returnSTART_STICKY; } @Override publicvoidonDestroy(){ super.onDestroy(); //利用interrupt方式中断该线程 isStop=true; Log.v("ServiceLife","onDestroy方法被调用"); } }
5、最后别忘了注册AndroidManifest.xml
<uses-permissionandroid:name="android.permission.INTERNET"/> <uses-permissionandroid:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"> </uses-permission> <uses-permissionandroid:name="android.permission.WRITE_EXTERNAL_STORAGE"> </uses-permission> <serviceandroid:name=".DownService"></service>
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。