Android文件傳輸

socket定義


    socket通常也稱作"套接字",實現服務器和客戶端之間的物理連接,並進行數據傳輸,主要有UDP和TCP兩個協議。Socket處於網絡協議的傳輸層。下面通過具體的例子來說明socket的一些常見用法。(下載請見底部)

Android客戶端/java客戶端

代碼:

package com.example.eric.mylibrary;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.net.Socket;

/**
 * 發送文件
 * Created by Eric_ on 2018/7/22.
 */

public class SocketDemo {
    public static void main(String[] a){
        final String path = "xxxx";//文件路徑
        final String fileName = "xxxx";//文件名稱
        final String ipAddress = "xxxx";//服務器ip地址
        final int port = xxxx;//服務器開放端口
        Thread sendThread = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println(FileSend(fileName, path, ipAddress, port));
            }
        });
        sendThread.start();
    }
    public static String FileSend(String fileName, String path, String ipAddress, int port){
        try {
            Socket socket = new Socket(ipAddress, port);//設置socket,並進行連接connect
            int bufferSize = 8192;
            byte[] buf = new byte[bufferSize];//數據存儲
            // 選擇進行傳輸的文件
            File file = new File(path + fileName);
            System.out.println("文件長度:" + (int) file.length());
            DataInputStream input = new DataInputStream(new FileInputStream(path + fileName));
            DataOutputStream output = new DataOutputStream(socket.getOutputStream());//將socket設置爲數據的傳輸出口
            DataInputStream getAck = new DataInputStream(socket.getInputStream());//設置socket數據的來源
            //將文件名傳輸過去
            output.writeUTF(file.getName());
            output.flush();
            //將文件長度傳輸過去
            output.writeLong((long) file.length());
            output.flush();

            int readSize = 0;

            while(true)
            {
                if(input != null)
                {
                    readSize = input.read(buf);
                }
                if(readSize == -1)
                    break;

                output.write(buf, 0, readSize);

                if(!getAck.readUTF().equals("OK"))
                {
                    System.out.println("服務器"+ ipAddress + ":" + port + "失去連接!");
                    break;
                }
            }
            output.flush();// 注意關閉socket鏈接,不然客戶端會等待server的數據過來,// 直到socket超時,導致數據不完整。
            input.close();
            output.close();
            socket.close();
            getAck.close();
            System.out.println("文件傳輸完成");
            return fileName + " 發送完成";
        } catch (Exception e) {
            return "發送錯誤:\n" + e.getMessage();
        }
    }
}

服務器:

代碼:

package com.example.eric.mylibrary;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;


/**
 * 服務端,接受文件
 * Created by Eric_ on 2018/7/22.
 */

public class AcceptSocketFile {
    static boolean isEnable;
    private static ServerSocket server;
    static int port = xxxx;
    public static void main(String[] a) {
        final String path = "xxxx"; //接受文件路徑
//         服務器端用於監聽Socket的線程
        Thread listener = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    server = new ServerSocket(port);
                } catch (IOException e) {
                    e.printStackTrace();
                }
                if (server != null) {
                    while (true) {
                        ReceiveFile(path);
                    }
                }
            }
        });
        listener.start();
    }
    public static String ReceiveFile(String path) {
        try {
            Socket socket = server.accept();
            System.out.println("客戶端"+ socket.getInetAddress() +"已連接");
            int bufferSize = 8192;
            byte[] buf = new byte[bufferSize];//數據存儲
            long donelen = 0;//傳輸完成的數據長度
            long filelen = 0;//文件長度
            //將socket數據作爲數據輸入流
            DataInputStream input = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
            //以客戶端的IP地址作爲存儲路徑
            String fileDir = path + "\\" + socket.getInetAddress().toString().substring(1, socket.getInetAddress().toString().length());;
            File file = new File(fileDir);
            //判斷文件夾是否存在,不存在則創建
            if(!file.exists())
            {
                file.mkdir();
            }

            String fileName = input.readUTF();//讀取文件名

            //設置文件路徑
            String filePath = fileDir + "\\" + fileName;


            file = new File(filePath);

            if(!file.exists())
            {
                file.createNewFile();
            }

            DataOutputStream fileOut = new DataOutputStream(
                    new BufferedOutputStream(new FileOutputStream(file)));


            filelen = input.readLong();//讀取文件長度

            System.out.println("文件的長度爲:" + filelen + "\n");
            System.out.println("開始接收文件!" + "\n");
            DataOutputStream ack = new DataOutputStream(socket.getOutputStream());

            while (true) {
                int read = 0;
                if (input != null) {
                    read = input.read(buf);
                    ack.writeUTF("OK");//結束到數據以後給client一個回覆
                }

                if (read == -1) {
                    break;
                }
                donelen += read;
                // 下面進度條本爲圖形界面的prograssBar做的,這裏如果是打文件,可能會重複打印出一些相同的百分比
                System.out.println("文件接收了" + (donelen * 100 / filelen)
                        + "%\n");
                fileOut.write(buf, 0, read);
            }

            if(donelen == filelen)
                System.out.println("接收完成,文件存爲" + file + "\n");
            else
            {
                System.out.printf("IP:%s發來的%s傳輸過程中失去連接\n",socket.getInetAddress(),fileName);
                file.delete();
            }
            ack.close();
            input.close();
            fileOut.close();
            return fileDir+"接受完成";
        } catch (Exception e) {
            return "接收錯誤:\n" + e.getMessage();
        }
    }
}

備註:如果是租的服務器,最好通過官網來開啓端口,通過Linux指令開啓的端口,在某些平臺上有限制。文件傳輸的格式沒有要求。

版權聲明:--------------------------------------------博文可隨意轉載,但請註明出處,謝謝!-------------------------------------------- https://blog.csdn.net/weixin_42474261/article/details/81182375

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章