簡體   English   中英

Java通過套接字傳輸多文件

[英]Java multiple file transfer over socket

好的,嘗試通過套接字傳輸指定的文件目錄,從數組列表中刪除目錄對象,因此只剩下文件,並通過同一個套接字 1 個 1 傳輸它們。 這里的arraylist 只填充了文件,沒有目錄。 這里分別是客戶端和服務器的接收和發送代碼。 代碼運行良好,沒有錯誤,除了所有數據都被寫入第一個文件。 后續文件在服務器文件夾中創建,但它們是 0 字節。 任何投入將不勝感激。

這是接收文件的服務器代碼

public void receive(){


    try {
        DataInputStream dis = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
        DataOutputStream dos = new DataOutputStream(new BufferedOutputStream(socket.getOutputStream()));
//read the number of files from the client
        int number = dis.readInt();
        ArrayList<File>files = new ArrayList<File>(number);
        System.out.println("Number of Files to be received: " +number);
        //read file names, add files to arraylist
        for(int i = 0; i< number;i++){
            File file = new File(dis.readUTF());
            files.add(file);
        }
        int n = 0;
        byte[]buf = new byte[4092];

        //outer loop, executes one for each file
        for(int i = 0; i < files.size();i++){

            System.out.println("Receiving file: " + files.get(i).getName());
            //create a new fileoutputstream for each new file
            FileOutputStream fos = new FileOutputStream("C:\\users\\tom5\\desktop\\salestools\\" +files.get(i).getName());
            //read file
            while((n = dis.read(buf)) != -1){
                fos.write(buf,0,n);
                fos.flush();
            }
            fos.close();
        }

    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();

    }


}

這是發送文件的客戶端代碼

public void send(ArrayList<File>files){

    try {
        DataInputStream dis = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
        DataOutputStream dos = new DataOutputStream(new BufferedOutputStream(socket.getOutputStream()));
        System.out.println(files.size());
//write the number of files to the server
        dos.writeInt(files.size());
        dos.flush();

        //write file names 
        for(int i = 0 ; i < files.size();i++){
            dos.writeUTF(files.get(i).getName());
            dos.flush();
        }

        //buffer for file writing, to declare inside or outside loop?
        int n = 0;
        byte[]buf = new byte[4092];
        //outer loop, executes one for each file
        for(int i =0; i < files.size(); i++){

            System.out.println(files.get(i).getName());
            //create new fileinputstream for each file
            FileInputStream fis = new FileInputStream(files.get(i));

            //write file to dos
            while((n =fis.read(buf)) != -1){
                dos.write(buf,0,n);
                dos.flush();

            }
            //should i close the dataoutputstream here and make a new one each time?
        }
        //or is this good?
        dos.close();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }


}

您正在讀取套接字,直到read()返回 -1。 這是流結束條件 (EOS)。 EOS 在對等方關閉連接時發生。 不是當它完成寫入一個文件時。

您需要在每個文件之前發送文件大小。 您已經對文件計數做了類似的事情。 然后確保您為該文件讀取了那么多字節:

String filename = dis.readUTF();
long fileSize = dis.readLong();
FileOutputStream fos = new FileOutputStream(filename);
while (fileSize > 0 && (n = dis.read(buf, 0, (int)Math.min(buf.length, fileSize))) != -1)
{
  fos.write(buf,0,n);
  fileSize -= n;
}
fos.close();

您可以將所有這些都包含在一個循環中,該循環在readUTF()拋出EOFException時終止。 相反,在發送數據之前,您當然必須在發送方調用writeUTF(filename)writeLong(filesize)

我是這樣做的,它工作得很好,你可以看看:

發送

byte[] done = new byte[3];
String str = "done";  //randomly anything
done = str.getBytes();
for (int i = 0; i < files.size(); i++) {
    System.out.println(files.get(i).getName());
    FileInputStream fis = new FileInputStream(files.get(i));
    while ((n = fis.read(buf)) != -1) {
        dos.write(buf, 0, n);
        System.out.println(n);
        dos.flush();
    }
    //should i close the dataoutputstream here and make a new one each time?                 
    dos.write(done, 0, 3);
    dos.flush();
}
//or is this good?
dos.close();

收到

for (int i = 0; i < files.size(); i++) {
    System.out.println("Receiving file: " + files.get(i).getName());
    //create a new fileoutputstream for each new file
    fos = new FileOutputStream("C:\\users\\tom5\\desktop\\salestools\\" + files.get(i).getName());
    //read file
    while ((n = dis.read(buf)) != -1 && n != 3) {
        fos.write(buf, 0, n);
        fos.flush();
    }
    fos.close();
}

我已經創建了一個服務器和客戶端。 他們正在建立連接,然后該服務器每秒發送 1MB 文本文件。 服務器和客戶端代碼如下。 我已經測試了很長時間,發現沒有數據丟失。 我稍微修改了上面的回答。

服務器代碼:

package com.dd.server;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.concurrent.TimeUnit;

public class Server {

public static void main(String[] args) throws InterruptedException {
    try {
        byte[] done = new byte[3];
        String str = "done";  //randomly anything
        done = str.getBytes();
        ServerSocket ss = new ServerSocket(5000); 
        Socket socket = ss.accept();
        byte[] mybytearray = new byte[4096];
        OutputStream os = socket.getOutputStream();
       
        TimeUnit.SECONDS.sleep(5);
        while(true) {
            DataOutputStream dos = new DataOutputStream(os);
            File myFile= new File("I:\\MY-LEARNINGS\\JAVA\\Workspace\\server\\src\\com\\dd\\server\\gistfile1.txt");
            dos.writeUTF(myFile.getName());     
            dos.writeLong(myFile.length());
            FileInputStream fis = new FileInputStream(myFile);  
            BufferedInputStream bis = new BufferedInputStream(fis);
            DataInputStream dis = new DataInputStream(bis);
            int read;
            System.out.println("---------File Writing started----------");
            int count = 0;
            while((read = dis.read(mybytearray)) != -1){
                dos.write(mybytearray, 0, read);
                dos.flush();
                ++count;
                System.out.println("Writing sub component of file. Step : "+count);
            }
            System.out.println("---------File Writing ended----------");
            System.out.println("Flushing data DONE command sent.");
            dis.close();
            bis.close();
            fis.close();
            TimeUnit.SECONDS.sleep(1);
            System.out.println("File transfer has been completed.");
            dos.write(done, 0, 3);
            dos.flush();
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
  }
}

客戶代碼:

 package clientcom.dd.clent;

 import java.io.DataInputStream;
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.net.Socket;

public class Client {

public static void main(String[] args) {
    try {
        Socket socket = new Socket("127.0.0.1", 5000);
        InputStream in = socket.getInputStream();
        DataInputStream dis = new DataInputStream(in);
        while(true) {
            FileOutputStream fos = 
                    new FileOutputStream("I:\\MY-LEARNINGS\\JAVA\\Workspace\\client\\"+System.currentTimeMillis()+"-data.txt");
            int read = 0;
            byte[] mybytearray = new byte[4096];
            while ((read = dis.read(mybytearray)) != -1 && read != 3) {
                fos.write(mybytearray, 0, read);
                fos.flush();
            }
            fos.close();
            //System.out.println("The value of read : "+read);
           // System.out.println("File has been received successfully.");
        }
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}
}

暫無
暫無

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

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