欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android TCP 文件客户端与服务器DEMO介绍

程序员文章站 2022-10-09 14:04:03
主要功能是: 1、tcp服务器提供文件下载服务,服务器支持多线程。 2、tcp client从服务器上下载指定的文件,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" />