首页 > 编程 > Java > 正文

java基于Socket做一个简单下载器

2019-11-26 13:56:11
字体:
来源:转载
供稿:网友

本文实例为大家分享了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>

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持武林网。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表