Android TCP 文件客户端文件下载与服务器

来源:互联网 发布:拍照识字软件app 编辑:程序博客网 时间:2024/06/05 00:56

转自:http://blog.csdn.net/chenlei1889/article/details/6367410


主要功能是:

1、TCP服务器提供文件下载服务,服务器支持多线程。

2、TCP Client从服务器上下载指定的文件,Client也支持多线程。

 

首先是服务器,服务器是在PC机上,JAVA运行环境,主要参考网上的代码,自己做了支持多线程处理,代码如下:

view plainprint?
  1. //file:DownloadServer.java     
  2. import java.net.*;    
  3. import java.io.*;    
  4. class ServerOneDownload extends Thread {    
  5.     private Socket socket = null;    
  6.     private String downloadRoot = null;    
  7.     private static final int Buffer = 8 * 1024;    
  8.     public ServerOneDownload(Socket socket, String downloadRoot) {    
  9.         super();    
  10.         this.socket = socket;    
  11.         this.downloadRoot = downloadRoot;    
  12.         start();    
  13.     }    
  14.     // 检查文件是否真实存在,核对下载密码,若文件不存在或密码错误,则返回-1,否则返回文件长度    
  15.     // 此处只要密码不为空就认为是正确的    
  16.     private long getFileLength(String fileName, String password) {    
  17.         // 若文件名或密码为null,则返回-1    
  18.         if ((fileName == null) || (password == null))    
  19.             return -1;    
  20.         // 若文件名或密码长度为0,则返回-1    
  21.         if ((fileName.length() == 0) || (password.length() == 0))    
  22.             return -1;    
  23.         String filePath = downloadRoot + fileName; // 生成完整文件路径    
  24.         System.out.println("DownloadServer getFileLength----->" + filePath);    
  25.         File file = new File(filePath);    
  26.         // 若文件不存在,则返回-1    
  27.         if (!file.exists())    
  28.             return -1;    
  29.         return file.length(); // 返回文件长度    
  30.     }    
  31.     // 用指定输出流发送指定文件    
  32.     private void sendFile(DataOutputStream out, String fileName)    
  33.             throws Exception {    
  34.         String filePath = downloadRoot + fileName; // 生成完整文件路径    
  35.         // 创建与该文件关联的文件输入流    
  36.         FileInputStream in = new FileInputStream(filePath);    
  37.         System.out.println("DownloadServer sendFile----->" + filePath);    
  38.         byte[] buf = new byte[Buffer];    
  39.         int len;    
  40.         // 反复读取该文件中的内容,直到读到的长度为-1    
  41.         while ((len = in.read(buf)) >= 0) {    
  42.             out.write(buf, 0, len); // 将读到的数据,按读到的长度写入输出流    
  43.             out.flush();    
  44.         }    
  45.         out.close();    
  46.         in.close();    
  47.     }    
  48.     // 提供下载服务    
  49.     public void download() throws IOException {    
  50.         System.out.println("启动下载... ");    
  51.         System.out.println("DownloadServer currentThread--->"    
  52.                 + currentThread().getName());    
  53.         System.out.println("DownloadServer currentThread--->"    
  54.                 + currentThread().getId());    
  55.         // 获取socket的输入流并包装成BufferedReader    
  56.         BufferedReader in = new BufferedReader(new InputStreamReader(    
  57.                 socket.getInputStream()));    
  58.         // 获取socket的输出流并包装成DataOutputStream    
  59.         DataOutputStream out = new DataOutputStream(socket.getOutputStream());    
  60.         try {    
  61.             String parameterString = in.readLine(); // 接收下载请求参数    
  62.             // 下载请求参数字符串为自定义的格式,由下载文件相对于下载根目录的路径和    
  63.             // 下载密码组成,两者间以字符 "@ "分隔,此处按 "@ "分割下载请求参数字符串    
  64.             String[] parameter = parameterString.split("@ ");    
  65.             String fileName = parameter[0]; // 获取相对文件路径    
  66.             String password = parameter[1]; // 获取下载密码    
  67.             // 打印请求下载相关信息    
  68.             System.out.print(socket.getInetAddress().getHostAddress()    
  69.                     + "提出下载请求, ");    
  70.             System.out.println("请求下载文件: " + fileName);    
  71.             // 检查文件是否真实存在,核对下载密码,获取文件长度    
  72.             long len = getFileLength(fileName, password);    
  73.             System.out.println("download fileName----->" + fileName);    
  74.             System.out.println("download password----->" + password);    
  75.             out.writeLong(len); // 向客户端返回文件大小    
  76.             out.flush();    
  77.             // 若获取的文件长度大于等于0,则允许下载,否则拒绝下载    
  78.             if (len >= 0) {    
  79.                 System.out.println("允许下载 ");    
  80.                 System.out.println("正在下载文件 " + fileName + "... ");    
  81.                 sendFile(out, fileName); // 向客户端发送文件    
  82.                 System.out.println(fileName +": "+"下载完毕 ");    
  83.             } else {    
  84.                 System.out.println("下载文件不存在或密码错误,拒绝下载! ");    
  85.             }    
  86.         } catch (Exception e) {    
  87.             System.out.println(e.toString());    
  88.         } finally {    
  89.             socket.close(); // 关闭socket    
  90.         }    
  91.     }    
  92.     @Override    
  93.     public void run() {    
  94.         try {    
  95.             download();    
  96.         } catch (IOException e) {    
  97.             // TODO Auto-generated catch block    
  98.             e.printStackTrace();    
  99.         }    
  100.         // TODO Auto-generated method stub    
  101.         super.run();    
  102.     }    
  103. }    
  104. public class DownloadServer {    
  105.     private final static int port = 65525;    
  106.     private static String root = "C:// "; // 下载根目录    
  107.     public static void main(String[] args) throws IOException {    
  108.         String temp = null;    
  109.         // 监听端口    
  110.         try {    
  111.             // 包装标准输入为BufferedReader    
  112.             BufferedReader systemIn = new BufferedReader(new InputStreamReader(    
  113.                     System.in));    
  114.             while (true) {    
  115.                 System.out.print("请输入下载服务器的下载根目录: ");    
  116.                 root = systemIn.readLine().trim(); // 从标准输入读取下载根目录    
  117.                 File file = new File(root);    
  118.                 // 若该目录确实存在且为目录,则跳出循环    
  119.                 if ((file.exists()) && (file.isDirectory())) {    
  120.                     temp = root.substring(root.length() - 1, root.length());    
  121.                     if (!temp.equals("//"))    
  122.                         root += "//";    
  123.                 }    
  124.                 break;    
  125.             }    
  126.         } catch (Exception e) {    
  127.             System.out.println(e.toString());    
  128.         }    
  129.         ServerSocket serverSocket = new ServerSocket(port);    
  130.         System.out.println("Server start...");    
  131.         try {    
  132.             while (true) {    
  133.                 Socket socket = serverSocket.accept();    
  134.                 new ServerOneDownload(socket, root);    
  135.             }    
  136.         } finally {    
  137.             serverSocket.close();    
  138.         }    
  139.     }    
  140. }    
 

File Download Client

Client输入IP和文件名即可直接从服务器上下载,还是看代码。

view plainprint?
  1. //file:DownLoadClient.java     
  2. package org.piaozhiye.study;    
  3. import java.io.IOException;    
  4. import java.net.Socket;    
  5. import android.app.Activity;    
  6. import android.os.Bundle;    
  7. import android.view.View;    
  8. import android.widget.Button;    
  9. import android.widget.EditText;    
  10. public class DownLoadClient extends Activity {    
  11.     private Button download = null;    
  12.     private EditText et_serverIP = null;    
  13.     private EditText et_fileName= null;    
  14.     private String downloadFile = null;    
  15.     private final static int PORT = 65525;    
  16.     private final static String defaultIP = "192.168.0.100";    
  17.     private static String serverIP = null;    
  18.     private Socket socket;    
  19.     /** Called when the activity is first created. */    
  20.     @Override    
  21.     public void onCreate(Bundle savedInstanceState) {    
  22.         super.onCreate(savedInstanceState);    
  23.         setContentView(R.layout.main);    
  24.         download = (Button)findViewById(R.id.download);    
  25.         et_serverIP= (EditText)findViewById(R.id.et_serverip);    
  26.         et_fileName = (EditText)findViewById(R.id.et_filename);    
  27.         et_serverIP.setText("192.168.0.100");    
  28.           
  29.       download.setOnClickListener(new View.OnClickListener() {    
  30.                 
  31.             @Override    
  32.             public void onClick(View v) {    
  33.                  serverIP = et_serverIP.getText().toString();    
  34.                  if(serverIP == null){    
  35.                      serverIP = defaultIP;    
  36.                  }    
  37.                  System.out.println("DownLoadClient serverIP--->" + serverIP );    
  38.                     System.out.println("DownLoadClient MainThread--->" + Thread.currentThread().getId() );    
  39.                         
  40.                 try{    
  41.                     socket = new Socket(serverIP, PORT);    
  42.                         
  43.                 }catch(IOException e){    
  44.                         
  45.                 }    
  46.                  downloadFile = et_fileName.getText().toString();    
  47.             Thread downFileThread = new Thread(new DownFileThread(socket, downloadFile));    
  48.             downFileThread.start();    
  49.                 System.out.println("DownLoadClient downloadFile--->" + downloadFile );    
  50.             }    
  51.         });    
  52.            
  53.     }    
  54. }    
 

file:DownFileThread.java

view plainprint?
  1. package org.piaozhiye.study;    
  2. import java.io.BufferedInputStream;    
  3. import java.io.DataInputStream;    
  4. import java.io.FileOutputStream;    
  5. import java.io.IOException;    
  6. import java.io.OutputStreamWriter;    
  7. import java.io.PrintWriter;    
  8. import java.net.Socket;    
  9. public class DownFileThread extends Thread {    
  10.     private Socket socket;    
  11.     private String downloadFile;    
  12.     private final static int Buffer = 8 * 1024;    
  13.     public DownFileThread(Socket socket, String downloadFile) {    
  14.         super();    
  15.         this.socket = socket;    
  16.         this.downloadFile = downloadFile;    
  17.     }    
  18.     public Socket getSocket() {    
  19.         return socket;    
  20.     }    
  21.     public void setSocket(Socket socket) {    
  22.         this.socket = socket;    
  23.     }    
  24.     public String getDownloadFile() {    
  25.         return downloadFile;    
  26.     }    
  27.     public void setDownloadFile(String downloadFile) {    
  28.         this.downloadFile = downloadFile;    
  29.     }    
  30.     // 向服务器提出下载请求,返回下载文件的大小    
  31.     private long request(String fileName, String password) throws IOException {    
  32.         // 获取socket的输入流并包装成DataInputStream    
  33.         DataInputStream in = new DataInputStream(socket.getInputStream());    
  34.         // 获取socket的输出流并包装成PrintWriter    
  35.         PrintWriter out = new PrintWriter(new OutputStreamWriter(    
  36.                 socket.getOutputStream()));    
  37.         // 生成下载请求字符串    
  38.         String requestString = fileName + "@ " + password;    
  39.         out.println(requestString); // 发出下载请求    
  40.         out.flush();    
  41.         return in.readLong(); // 接收并返回下载文件长度    
  42.     }    
  43.     // 接收并保存文件    
  44.     private void receiveFile(String localFile) throws Exception {    
  45.         // 获取socket的输入流并包装成BufferedInputStream    
  46.         BufferedInputStream in = new BufferedInputStream(    
  47.                 socket.getInputStream());    
  48.         // 获取与指定本地文件关联的文件输出流    
  49.         FileOutputStream out = new FileOutputStream(localFile);    
  50.         byte[] buf = new byte[Buffer];    
  51.         int len;    
  52.         // 反复读取该文件中的内容,直到读到的长度为-1    
  53.         while ((len = in.read(buf)) >= 0) {    
  54.             out.write(buf, 0, len); // 将读到的数据,按读到的长度写入输出流    
  55.             out.flush();    
  56.         }    
  57.         out.close();    
  58.         in.close();    
  59.     }    
  60.     // 从服务器下载文件    
  61.     public void download(String downloadFile) throws Exception {    
  62.         try {    
  63.             String password = "password";    
  64.             // String downloadFile ="imissyou.mp3";    
  65.             String localpath = "/sdcard/";    
  66.             String localFile = localpath + downloadFile;    
  67.             long fileLength = request(downloadFile, password);    
  68.             // 若获取的文件长度大于等于0,说明允许下载,否则说明拒绝下载    
  69.             if (fileLength >= 0) {    
  70.                 System.out.println("fileLength: " + fileLength + " B");    
  71.                 System.out.println("downing...");    
  72.                 receiveFile(localFile); // 从服务器接收文件并保存至本地文件    
  73.                 System.out.println("file:" + downloadFile + " had save to "    
  74.                         + localFile);    
  75.             } else {    
  76.                 System.out.println("download " + downloadFile + " error! ");    
  77.             }    
  78.         } catch (IOException e) {    
  79.             System.out.println(e.toString());    
  80.         } finally {    
  81.             socket.close(); // 关闭socket    
  82.         }    
  83.     }    
  84.     @Override    
  85.     public void run() {    
  86.         System.out.println("DownFileThread currentThread--->"    
  87.                 + DownFileThread.currentThread().getId());    
  88.         // TODO Auto-generated method stub    
  89.         try {    
  90.             download(downloadFile);    
  91.         } catch (Exception e) {    
  92.             // TODO Auto-generated catch block    
  93.             e.printStackTrace();    
  94.         }    
  95.         super.run();    
  96.     }    
  97.         
  98. }    
 

layout.xml

view plainprint?
  1. <?xml version="1.0" encoding="utf-8"?>    
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    
  3.     android:orientation="vertical"    
  4.     android:layout_width="fill_parent"    
  5.     android:layout_height="fill_parent"    
  6.     >    
  7. <TextView     
  8.     android:layout_width="wrap_content"     
  9.     android:layout_height="wrap_content"     
  10.     android:paddingLeft="10dp"    
  11.     android:paddingRight="10dp"    
  12.     android:paddingTop="5dp"    
  13.     android:paddingBottom="5dp"    
  14.     android:text="服务器IP:"    
  15.     />    
  16.     <EditText    
  17.     android:id="@+id/et_serverip"    
  18.     android:layout_width="fill_parent"    
  19.     android:layout_height="wrap_content"    
  20.     android:paddingLeft="10dp"    
  21.     android:paddingRight="10dp"    
  22.     android:paddingTop="5dp"    
  23.     android:paddingBottom="5dp"    
  24.         
  25.     />    
  26.         
  27.     <TextView     
  28.     android:layout_width="wrap_content"     
  29.     android:layout_height="wrap_content"     
  30.     android:paddingLeft="10dp"    
  31.     android:paddingRight="10dp"    
  32.     android:paddingTop="5dp"    
  33.     android:paddingBottom="5dp"    
  34.     android:text="下载文件名:"    
  35.     />    
  36.     <EditText    
  37.     android:id="@+id/et_filename"    
  38.     android:layout_width="fill_parent"    
  39.     android:layout_height="wrap_content"    
  40.     android:paddingLeft="10dp"    
  41.     android:paddingRight="10dp"    
  42.     android:paddingTop="5dp"    
  43.     android:paddingBottom="5dp"    
  44.         
  45.     />    
  46.     <Button    
  47.     android:id="@+id/download"    
  48.     android:layout_width="fill_parent"    
  49.     android:layout_height="wrap_content"    
  50.     android:text="download"    
  51.     />    
  52. </LinearLayout>    
 

同时别忘了权限:

<uses-permission android:name="android.permission.INTERNET" />