簡體   English   中英

如何在客戶端和服務器之間傳輸多個文件?

[英]How to transfer multiple files between client and server?

我重寫了服務器和客戶端之間文件傳輸代碼的簡單示例。

而且有效。

但我想使其能夠在特定目錄中傳輸多個文件。 用戶將寫入文件名(位於該特定目錄中),客戶端將從服務器下載它們。 我怎樣才能做到這一點? 有任何想法嗎? 謝謝。

客戶代碼:

    import java.net.*;
    import java.io.*;

    public class Client {

        static String hostname = "127.0.0.1";
        static int port = 4588;
        static int processedByte; 
        static byte[] theByte = new byte[1];

        static Socket client = null; 
          static InputStream inuputSt = null; 

        public static void main(String[] args) throws InterruptedException {
            System.out.println("connecting...");
            Thread.sleep(500);
            try { 
                client = new Socket(hostname, port); 
                inuputSt = client.getInputStream(); 
            } catch (IOException ex) { 
                System.out.println("connection error.");
            } 

            ByteArrayOutputStream arrayOutput = new ByteArrayOutputStream(); 

            if (inuputSt != null) { 

                FileOutputStream fileOutput = null; 
                BufferedOutputStream bufferedOutput = null; 
                try { 
                    System.out.println("downloading target file...");
                    Thread.sleep(800);
                    fileOutput = new FileOutputStream("file1_downloaded.txt"); 
                    bufferedOutput = new BufferedOutputStream(fileOutput); 
                    processedByte = inuputSt.read(theByte, 0, theByte.length); 

                    do { 
                            arrayOutput.write(theByte); 
                            processedByte = inuputSt.read(theByte); 
                    } while (processedByte != -1); 

                    bufferedOutput.write(arrayOutput.toByteArray()); 
                    bufferedOutput.flush(); 
                    bufferedOutput.close(); 
                    System.out.println("file downloaded");
                    client.close(); 
                } catch (IOException ex) { 
                    System.out.println("file transfer error."); 
                } 
            }

        }
    }

服務器代碼:

import java.net.*;
import java.io.*;

public class Server {
static int port = 4588;
public static void main(String[] args) {

    while (true) {
        ServerSocket server = null; 
        Socket connection = null; 
        BufferedOutputStream bufferedOutput = null; 

        try { 
            server = new ServerSocket(port); 
            connection = server.accept(); 
            bufferedOutput = new BufferedOutputStream(connection.getOutputStream()); 
        } catch (IOException ex) { 
            // Do exception handling 
        } 

        if (bufferedOutput != null) { 
            File fileToSend = new File("files\\file1.txt"); 
            byte[] mybytearray = new byte[(int) fileToSend.length()]; 

            FileInputStream fileInputSt = null; 

            try { 
                fileInputSt = new FileInputStream(fileToSend); 
            } catch (FileNotFoundException ex) { 
                // exception stuff
            } 
            BufferedInputStream bufferedInput = new BufferedInputStream(fileInputSt); 

            try { 
                bufferedInput.read(mybytearray, 0, mybytearray.length); 
                bufferedOutput.write(mybytearray, 0, mybytearray.length); 
                bufferedOutput.flush(); 
                bufferedOutput.close(); 
                connection.close(); 

                //file1.txt has been downloaded
                return; 
            } catch (IOException ex) { 
                // exception stuff
            } 
        } 
    } 
}

}

您建議將HTTP作為客戶端和服務器的協議-HTTP是一種很好的協議,但是如果您想自己完成全部操作,則可能是一個很大的實現障礙。 HTTP PUT動詞可用於上載文件,以這種方式使用HTTP的好處是您的客戶端和服務器可以與其他旨在使用PUT請求的工具進行通信。 PUT的使用少於其他HTTP動詞,因此並非所有HTTP工具都可以使用; curl(1)程序確實通過-T命令行選項支持PUT 。如果您選擇HTTP,這將是一個很好的實現輔助。)

有各種各樣的REST框架可以幫助您編寫HTTP軟件。 我聽說過Restlet的好消息,這是我建議的起點。

但是,你沒有挑HTTP作為協議。 我認為,如果您實現自己的協議,您會學到很多有關網絡編程的知識-它會通過使用預寫的HTTP協議工具很難學習的方式,向您學習有關API設計和套接字編程的很多知識(並且令人沮喪如果您嘗試自己完全實現HTTP)。

考慮以下對話:

客戶端->服務器:上傳名為“ flubber”的文件,大小為200000字節
服務器->客戶端:確定
客戶端->服務器: Flubber目錄
服務器->客戶端:確定
客戶端->服務器:上傳名為“ blort”的文件,大小為10個字節
服務器->客戶端:錯誤,文件存在
...

您可能希望添加新命令以提供對文件進行哈希處理的兩端,以確保文件傳輸成功,發送特定字節范圍的命令(追加到現有文件或重新啟動失敗的傳輸),列出現有命令服務器上的文件名,覆蓋現有文件的命令,從服務器上刪除文件的命令等等。 編寫自己的協議的最好的部分是您可以決定程序將支持什么。 缺點是您必須測試所編寫的功能,並且測試某些情況可能很困難。 (說,考慮到客戶可以在不同的TCP數據包發送命令的每一個字符,實施緩沖存儲了一個完整的指令是不平凡的 ,但它已經做了你的工具如的Restlet。)

Juan提出的使用多個TCP會話的建議並不是絕對必要的-盡管對於您來說這可能是最簡單的方法。 您需要添加某種機制來向遠程對等方提供文件名,最好通過“控制”通道(第一個會話正在運行,類似於FTP)來完成,或者它可能是在發送文件之前立即發送的。文件的內容(類似於HTTP)。

但我想建議避免多個連接-每個連接需要兩次系統之間的往返時間來建立和開始傳輸字節。 這種延遲可能非常煩人,尤其是當您嘗試傳輸數百個小文件時。 與實際發送數據相比,您甚至可以花費更多的時間來建立連接。

但這是您的工具-您可以根據需要進行設計。 玩得開心。

我認為您需要為每個文件創建一個新的連接,這樣在這種情況下,您將能夠同時傳輸文件。

您可能需要修改服務器以為每個客戶端連接創建一個新線程(或從線程池中獲取一個線程),以便它可以同時使用多個線程。

然后,您可以為每個文件運行一次客戶端。

干杯

好的,您可以傳輸構成ArrayList或List文件的多個文件嗎? 進入文件系統路徑后進入陣列。 希望對您有幫助。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM