java基于Socket做一个简单下载器
程序员文章站
2024-03-13 12:48:57
本文实例为大家分享了java基于socket制作下载器的过程,及相关代码,供大家参考,具体内容如下
1.首先要建立一个服务器用来处理信息并给客户端传输文件(电脑)
&n...
本文实例为大家分享了java基于socket制作下载器的过程,及相关代码,供大家参考,具体内容如下
1.首先要建立一个服务器用来处理信息并给客户端传输文件(电脑)
我是用电脑开了一个wifi,手机连上后使用scoket传输的
serverip要根据自己实际情况更改。端口也可以随便更改0~65535,尽量选大一点
import java.io.bufferedinputstream; import java.io.bufferedoutputstream; import java.io.bufferedreader; import java.io.bufferedwriter; import java.io.file; import java.io.fileinputstream; import java.io.inputstreamreader; import java.io.outputstreamwriter; import java.io.printwriter; import java.net.serversocket; import java.net.socket; /** * 测试android客户端与pc服务器通过socket进行交互 服务器端:接收客户端的信息并回送给客户 * * @author ameyume * */ public class server implements runnable { //定义传输的ip和端口信息 public static final string serverip = "192.168.155.1"; //定义的9888端口 public static final int serverport = 9888; //定义文件 private file file = null; public static void main(string[] args) { //建立调用线程执行传输的方法 thread desktopserverthread = new thread(new server()); desktopserverthread.start(); } public void run() { try { system.out.println("s: connecting...9888"); //创建套接字 serversocket serversocket = new serversocket(serverport); while (true) { // 等待接受客户端请求 socket client = serversocket.accept(); system.out.println("s: receiving...9888"); try { // 接受客户端信息 bufferedreader in = new bufferedreader( new inputstreamreader(client.getinputstream())); system.out.println("s: 接收客户端信息"); // 读取客户端的信息 string str = in.readline(); string str1 = str.substring(0,2); string str2 = str.substring(2); system.out.println(str); //根据客户端的请求找到对应的文件并把文件大小的值传过去 if (str.equals("file_size")) { //定义你要传输的文件(我这里写的是e盘下的某个文件) file = new file("e:\\某个文件"); //输入流 fileinputstream fis = new fileinputstream(file); //输出流 bufferedinputstream bis = new bufferedinputstream(fis); //计算将要传输的文件大小 int sum = bis.available(); //将int型的文件大小转成字符串 string s = string.valueof(sum); system.out.println(s); //建立输出流以发送文件大小的信息 printwriter out = new printwriter(new bufferedwriter( new outputstreamwriter(client.getoutputstream())), true); //发送文件的大小信息 out.println(s); //关闭流 out.flush(); bis.close(); } else if (str1.equals("ok")) { int a = integer.parseint(str2); // 客户端收到文件大小的值后,再根据客户端传来的“ok”将文件传过去 bufferedoutputstream bos = new bufferedoutputstream( client.getoutputstream()); system.out.println("s: 开始传输"); //开始传输 if (true) { //输入流 fileinputstream fis = new fileinputstream(file); //跳过前面已经传输过的字节 fis.skip(a); //缓冲输入流 bufferedinputstream bis = new bufferedinputstream( fis); int t = -1; while ((t = bis.read()) >= 0) { bos.write(t); } string s = "已传输"; //关闭流 bos.flush(); bis.close(); bos.close(); // serversocket.close(); system.out.println("s: received: '" + s + "'"); } } else { system.out .println("not receiver anything from client!"); } } catch (exception e) { system.out.println("s: error 1"); e.printstacktrace(); } finally { client.close(); system.out.println("s: done."); } } } catch (exception e) { system.out.println("s: error 2"); e.printstacktrace(); } } }
2.再建立一个客户端,我这里用的是安卓写的mainactivity.java(我是在手机上运行的)
package com.xhy.zz; import android.app.activity; import android.content.intent; import android.os.bundle; import android.os.handler; import android.os.message; import android.view.view; import android.view.view.onclicklistener; import android.widget.button; import android.widget.textview; public class mainactivity extends activity { // 定义handler public static handler myhandler; // 定义intent private intent intent; // 获取控件 private textview text_name; private textview text_percent; private button btn_start; private button btn_stop; // 文件显示 private textview text_sel_file; @override protected void oncreate(bundle savedinstancestate) { // todo auto-generated method stub 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 = new handler() { @override public void handlemessage(message msg) { super.handlemessage(msg); if (msg.what == 0x0001) { bundle data = msg.getdata(); string str = data.getstring("value"); text_percent.settext(str); } } }; // 显式的方式调用helloservice intent = new intent(this, downservice.class); // 设置启动按钮点击事件 btn_start.setonclicklistener(new onclicklistener() { @override public void onclick(view v) { // 开启服务 startservice(intent); } }); // 设置停止按钮点击事件 btn_stop.setonclicklistener(new onclicklistener() { @override public void onclick(view v) { // 关闭服务 stopservice(intent); } }); } /*** * 被调用activity一旦返回值 该回调方法将被系统自动调用 */ @override protected void onactivityresult(int requestcode, int resultcode, intent intent) { super.onactivityresult(requestcode, resultcode, intent); // 如果请求码是0 // 并且返回的结果码为1 // 请求的activity可能返回多种结果码 if (requestcode == 0 && resultcode == 1) { // 取出数据 bundle data = intent.getextras(); string str = data.getstring("files"); // 显示数据 text_sel_file.settext(str); } } }
3.activity_main.xml文件
<?xml version="1.0" encoding="utf-8"?> <linearlayout xmlns: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用于在后台开启线程执行下载
package com.xhy.zz; import java.io.bufferedinputstream; import java.io.bufferedreader; import java.io.bufferedwriter; import java.io.file; import java.io.fileoutputstream; import java.io.inputstreamreader; import java.io.outputstreamwriter; import java.io.printwriter; import java.net.inetaddress; import java.net.socket; import java.net.unknownhostexception; import android.app.service; import android.content.context; import android.content.intent; import android.content.sharedpreferences; import android.os.bundle; import android.os.environment; import android.os.ibinder; import android.os.message; import android.util.log; public class downservice extends service { private static final string tag = "socket_android"; // preferece机制操作的文件名 public static final string preference_name = "downservice"; // preferece机制的操作模式 public static int mode = context.mode_private; // 线程 private thread workthread; // 定义文件名 private string filename="file"; // 端口号 private int port = 9888; private boolean isstop = false; /*** * 必须要实现的方法 */ @override public ibinder onbind(intent intent) { return null; } @override public void oncreate() { super.oncreate(); } @override public int onstartcommand(intent intent, int flags, int startid) { log.v("tcp", filename); // 建立传输的方法 runnable backgroundwork = new runnable() { @override public void run() { // settitle("测试socket连接"); socket socket = null; socket socket1 = null; try { /* * 指定server的ip地址,此地址为局域网地址,如果是使用wifi上网,则为pc机的wifi ip地址 * 在ipconfig查看到的ip地址如下: ethernet adapter 无线网络连接: * connection-specific dns suffix . : ip address. . . . * . . . . . . . . : 192.168.155.1 */ inetaddress serveraddr = inetaddress .getbyname("192.168.155.1");// tcpserver.serverip log.d("tcp", "c: connecting..."); log.d("tcp", filename + " " + port); // 应用server的ip和端口建立socket对象,向服务端发送请求获取文件大小的值 socket1 = new socket(serveraddr, port); string message = "---test_socket_android---"; log.d("tcp", "c: sending: '" + message + "'"); // 将信息通过这个对象来发送给server printwriter out = new printwriter(new bufferedwriter( new outputstreamwriter( socket1.getoutputstream())), true); // 把用户输入的内容发送给server out.println("file_size"); out.flush(); // 接收服务器信息 bufferedreader in = new bufferedreader( new inputstreamreader(socket1.getinputstream())); // 获取文件大小 string str1 = in.readline(); log.d("tcp", str1); // 将文件大小转成int型 int sum = integer.parseint(str1); log.d("tcp", str1); // 关闭输入流 in.close(); sharedpreferences sharedpreferences = getsharedpreferences( preference_name, mode); sharedpreferences.editor editor = sharedpreferences .edit(); //取出已经传输了的字节 int pre = sharedpreferences.getint("downservice", 0); int _pre = pre; //将其转化为字符串以便发送给服务端 string s = string.valueof(_pre); // 应用server的ip和端口建立socket对象再次向服务端发送请求,以获取文件内容 socket = new socket(serveraddr, port); // 向服务端发送请求获得文件的字符 printwriter out1 = new printwriter( new bufferedwriter(new outputstreamwriter( socket.getoutputstream())), true); out1.println("ok"+s); out1.flush(); out.close(); // 定义输入流 bufferedinputstream bis = new bufferedinputstream( socket.getinputstream()); string file1 = filename; string file; // 判断手机是否插入了sdcard,是则将文件插入内存卡 if (environment.getexternalstoragestate().equals( environment.media_mounted)) { file sdcard = environment .getexternalstoragedirectory(); // sd卡定义文件 file = sdcard.getcanonicalfile() + "/" + file1; // 定义文件输出流 fileoutputstream fos = new fileoutputstream(file,true); try { int t = -1; int downloaded = pre; // 定义每次传输的字节数 byte[] buff = new byte[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(); } // 获得文件传输的进度 float wb = ((downloaded * 100) / (float) sum); int wi = (int) wb; system.out.println(downloaded); string str = string.valueof(wi) + "%"; // 将文件的传输进度给送给baseactivity,以显示给用户 message msg = new message(); // 生成消息 // 生成消息 msg.what = 0x0001; // 设置消息类型 // 生成bundle携带数据 bundle data = new bundle(); data.putstring("value", str); msg.setdata(data); // 利用handler发送消息 mainactivity.myhandler.sendmessage(msg); } // 关闭输入输出流 bis.close(); fos.flush(); fos.close(); } catch (exception e) { bis.close(); fos.flush(); fos.close(); } } log.d(tag, "from server:'已接收" + "'"); } catch (unknownhostexception e) { log.e(tag, "192.168.155.1 is unkown server!"); } catch (exception e) { e.printstacktrace(); } finally { try { socket.close(); } catch (exception e) { e.printstacktrace(); } } } }; workthread = new thread(backgroundwork); // isalive方法用于判断workthread线程是否被开启 if (!workthread.isalive()) { // 生成新线程 workthread.start(); log.v("servicelife", "线程开始工作"); } else { log.v("workthread", "线程已经被调用"); } return start_sticky; } @override public void ondestroy() { super.ondestroy(); // 利用interrupt方式中断该线程 isstop = true; log.v("servicelife", "ondestroy方法被调用"); } }
5、最后别忘了注册androidmanifest.xml
<uses-permission android:name="android.permission.internet" /> <uses-permission android:name="android.permission.mount_unmount_filesystems" > </uses-permission> <uses-permission android:name="android.permission.write_external_storage" > </uses-permission> <service android:name=".downservice" ></service>
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
下一篇: C# 企业微信消息推送