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>
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。