Android TCP 文件客户端与服务器DEMO介绍
Android TCP 文件客户端与服务器DEMO介绍
发布时间:2016-12-28 来源:查字典编辑
摘要:主要功能是:1、TCP服务器提供文件下载服务,服务器支持多线程。2、TCPClient从服务器上下载指定的文件,Client也支持多线程。首...

主要功能是:

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

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

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

复制代码 代码如下:

//file:DownloadServer.java

import java.net.*;

import java.io.*;

class ServerOneDownload extends Thread {

private Socket socket = null;

private String downloadRoot = null;

private static final int Buffer = 8 * 1024;

public ServerOneDownload(Socket socket, String downloadRoot) {

super();

this.socket = socket;

this.downloadRoot = downloadRoot;

start();

}

// 检查文件是否真实存在,核对下载密码,若文件不存在或密码错误,则返回-1,否则返回文件长度

// 此处只要密码不为空就认为是正确的

private long getFileLength(String fileName, String password) {

// 若文件名或密码为null,则返回-1

if ((fileName == null) || (password == null))

return -1;

// 若文件名或密码长度为0,则返回-1

if ((fileName.length() == 0) || (password.length() == 0))

return -1;

String filePath = downloadRoot + fileName; // 生成完整文件路径

System.out.println("DownloadServer getFileLength----->" + filePath);

File file = new File(filePath);

// 若文件不存在,则返回-1

if (!file.exists())

return -1;

return file.length(); // 返回文件长度

}

// 用指定输出流发送指定文件

private void sendFile(DataOutputStream out, String fileName)

throws Exception {

String filePath = downloadRoot + fileName; // 生成完整文件路径

// 创建与该文件关联的文件输入流

FileInputStream in = new FileInputStream(filePath);

System.out.println("DownloadServer sendFile----->" + filePath);

byte[] buf = new byte[Buffer];

int len;

// 反复读取该文件中的内容,直到读到的长度为-1

while ((len = in.read(buf)) >= 0) {

out.write(buf, 0, len); // 将读到的数据,按读到的长度写入输出流

out.flush();

}

out.close();

in.close();

}

// 提供下载服务

public void download() throws IOException {

System.out.println("启动下载... ");

System.out.println("DownloadServer currentThread--->"

+ currentThread().getName());

System.out.println("DownloadServer currentThread--->"

+ currentThread().getId());

// 获取socket的输入流并包装成BufferedReader

BufferedReader in = new BufferedReader(new InputStreamReader(

socket.getInputStream()));

// 获取socket的输出流并包装成DataOutputStream

DataOutputStream out = new DataOutputStream(socket.getOutputStream());

try {

String parameterString = in.readLine(); // 接收下载请求参数

// 下载请求参数字符串为自定义的格式,由下载文件相对于下载根目录的路径和

// 下载密码组成,两者间以字符 "@ "分隔,此处按 "@ "分割下载请求参数字符串

String[] parameter = parameterString.split("@ ");

String fileName = parameter[0]; // 获取相对文件路径

String password = parameter[1]; // 获取下载密码

// 打印请求下载相关信息

System.out.print(socket.getInetAddress().getHostAddress()

+ "提出下载请求, ");

System.out.println("请求下载文件: " + fileName);

// 检查文件是否真实存在,核对下载密码,获取文件长度

long len = getFileLength(fileName, password);

System.out.println("download fileName----->" + fileName);

System.out.println("download password----->" + password);

out.writeLong(len); // 向客户端返回文件大小

out.flush();

// 若获取的文件长度大于等于0,则允许下载,否则拒绝下载

if (len >= 0) {

System.out.println("允许下载 ");

System.out.println("正在下载文件 " + fileName + "... ");

sendFile(out, fileName); // 向客户端发送文件

System.out.println(fileName +": "+"下载完毕 ");

} else {

System.out.println("下载文件不存在或密码错误,拒绝下载! ");

}

} catch (Exception e) {

System.out.println(e.toString());

} finally {

socket.close(); // 关闭socket

}

}

@Override

public void run() {

try {

download();

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

// TODO Auto-generated method stub

super.run();

}

}

public class DownloadServer {

private final static int port = 65525;

private static String root = "C:// "; // 下载根目录

public static void main(String[] args) throws IOException {

String temp = null;

// 监听端口

try {

// 包装标准输入为BufferedReader

BufferedReader systemIn = new BufferedReader(new InputStreamReader(

System.in));

while (true) {

System.out.print("请输入下载服务器的下载根目录: ");

root = systemIn.readLine().trim(); // 从标准输入读取下载根目录

File file = new File(root);

// 若该目录确实存在且为目录,则跳出循环

if ((file.exists()) && (file.isDirectory())) {

temp = root.substring(root.length() - 1, root.length());

if (!temp.equals("//"))

root += "//";

}

break;

}

} catch (Exception e) {

System.out.println(e.toString());

}

ServerSocket serverSocket = new ServerSocket(port);

System.out.println("Server start...");

try {

while (true) {

Socket socket = serverSocket.accept();

new ServerOneDownload(socket, root);

}

} finally {

serverSocket.close();

}

}

}

File Download Client

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

复制代码 代码如下:

//file:DownLoadClient.java

package org.piaozhiye.study;

import java.io.IOException;

import java.net.Socket;

import android.app.Activity;

import android.os.Bundle;

import android.view.View;

import android.widget.Button;

import android.widget.EditText;

public class DownLoadClient extends Activity {

private Button download = null;

private EditText et_serverIP = null;

private EditText et_fileName= null;

private String downloadFile = null;

private final static int PORT = 65525;

private final static String defaultIP = "192.168.0.100";

private static String serverIP = null;

private Socket socket;

/** Called when the activity is first created. */

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

download = (Button)findViewById(R.id.download);

et_serverIP= (EditText)findViewById(R.id.et_serverip);

et_fileName = (EditText)findViewById(R.id.et_filename);

et_serverIP.setText("192.168.0.100");

download.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

serverIP = et_serverIP.getText().toString();

if(serverIP == null){

serverIP = defaultIP;

}

System.out.println("DownLoadClient serverIP--->" + serverIP );

System.out.println("DownLoadClient MainThread--->" + Thread.currentThread().getId() );

try{

socket = new Socket(serverIP, PORT);

}catch(IOException e){

}

downloadFile = et_fileName.getText().toString();

Thread downFileThread = new Thread(new DownFileThread(socket, downloadFile));

downFileThread.start();

System.out.println("DownLoadClient downloadFile--->" + downloadFile );

}

});

}

}

file:DownFileThread.java

复制代码 代码如下:

package org.piaozhiye.study;

import java.io.BufferedInputStream;

import java.io.DataInputStream;

import java.io.FileOutputStream;

import java.io.IOException;

import java.io.OutputStreamWriter;

import java.io.PrintWriter;

import java.net.Socket;

public class DownFileThread extends Thread {

private Socket socket;

private String downloadFile;

private final static int Buffer = 8 * 1024;

public DownFileThread(Socket socket, String downloadFile) {

super();

this.socket = socket;

this.downloadFile = downloadFile;

}

public Socket getSocket() {

return socket;

}

public void setSocket(Socket socket) {

this.socket = socket;

}

public String getDownloadFile() {

return downloadFile;

}

public void setDownloadFile(String downloadFile) {

this.downloadFile = downloadFile;

}

// 向服务器提出下载请求,返回下载文件的大小

private long request(String fileName, String password) throws IOException {

// 获取socket的输入流并包装成DataInputStream

DataInputStream in = new DataInputStream(socket.getInputStream());

// 获取socket的输出流并包装成PrintWriter

PrintWriter out = new PrintWriter(new OutputStreamWriter(

socket.getOutputStream()));

// 生成下载请求字符串

String requestString = fileName + "@ " + password;

out.println(requestString); // 发出下载请求

out.flush();

return in.readLong(); // 接收并返回下载文件长度

}

// 接收并保存文件

private void receiveFile(String localFile) throws Exception {

// 获取socket的输入流并包装成BufferedInputStream

BufferedInputStream in = new BufferedInputStream(

socket.getInputStream());

// 获取与指定本地文件关联的文件输出流

FileOutputStream out = new FileOutputStream(localFile);

byte[] buf = new byte[Buffer];

int len;

// 反复读取该文件中的内容,直到读到的长度为-1

while ((len = in.read(buf)) >= 0) {

out.write(buf, 0, len); // 将读到的数据,按读到的长度写入输出流

out.flush();

}

out.close();

in.close();

}

// 从服务器下载文件

public void download(String downloadFile) throws Exception {

try {

String password = "password";

// String downloadFile ="imissyou.mp3";

String localpath = "/sdcard/";

String localFile = localpath + downloadFile;

long fileLength = request(downloadFile, password);

// 若获取的文件长度大于等于0,说明允许下载,否则说明拒绝下载

if (fileLength >= 0) {

System.out.println("fileLength: " + fileLength + " B");

System.out.println("downing...");

receiveFile(localFile); // 从服务器接收文件并保存至本地文件

System.out.println("file:" + downloadFile + " had save to "

+ localFile);

} else {

System.out.println("download " + downloadFile + " error! ");

}

} catch (IOException e) {

System.out.println(e.toString());

} finally {

socket.close(); // 关闭socket

}

}

@Override

public void run() {

System.out.println("DownFileThread currentThread--->"

+ DownFileThread.currentThread().getId());

// TODO Auto-generated method stub

try {

download(downloadFile);

} catch (Exception e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

super.run();

}

}

layout.xml

复制代码 代码如下:

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

android:orientation="vertical"

android:layout_width="fill_parent"

android:layout_height="fill_parent"

>

<TextView

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:paddingLeft="10dp"

android:paddingRight="10dp"

android:paddingTop="5dp"

android:paddingBottom="5dp"

android:text="服务器IP:"

/>

<EditText

android:id="@+id/et_serverip"

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:paddingLeft="10dp"

android:paddingRight="10dp"

android:paddingTop="5dp"

android:paddingBottom="5dp"

/>

<TextView

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:paddingLeft="10dp"

android:paddingRight="10dp"

android:paddingTop="5dp"

android:paddingBottom="5dp"

android:text="下载文件名:"

/>

<EditText

android:id="@+id/et_filename"

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:paddingLeft="10dp"

android:paddingRight="10dp"

android:paddingTop="5dp"

android:paddingBottom="5dp"

/>

<Button

android:id="@+id/download"

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:text="download"

/>

</LinearLayout>

同时别忘了权限:

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

推荐文章
猜你喜欢
附近的人在看
推荐阅读
拓展阅读
相关阅读
网友关注
最新安卓软件开发学习
热门安卓软件开发学习
编程开发子分类