简体   繁体   中英

Socket file transfer

In this code if the files are sent at the first time(no matter the number files i'm sending.) the code works fine. But when I put the FileSender in a loop to send files one by one, after the first transfer, the data received on the receiver's end is arbitrary(if checked during debugging) and it wouldn't even receive the files. Here's the change which I've done and it's not working.

FileSender.java

import java.io.OutputStream;
import java.io.File;
import java.net.Socket;
public class FileSender {
public  void main(Socket socket,String[] args) {
try {

  OutputStream os     = socket.getOutputStream();
  int cnt_files = args.length;

  // How many files?
  ByteStream.toStream(os, cnt_files);

  for (int cur_file=0; cur_file<cnt_files; cur_file++) {
    ByteStream.toStream(os, new File(args[cur_file]).getName());
    ByteStream.toStream(os, new File(args[cur_file]));
  }
}
catch (Exception ex) {
  ex.printStackTrace();
}
}
}

String[] args contains the path of the files to be transmitted.

FileReceiver.java

import java.io.File;
import java.io.InputStream;
import java.net.Socket;

public class FileReceiver {

public void main(Socket socket,String arg) {
try {
    InputStream in = socket.getInputStream();

  int nof_files = ByteStream.toInt(in);
System.out.println("reach 1     "+ nof_files);
  for (int cur_file=0;cur_file < nof_files; cur_file++) {
    String file_name = ByteStream.toString(in);

    File file=new File(arg+file_name);
    System.out.println("Received path is :  "+file);
    ByteStream.toFile(in, file);
  }

}
catch (java.lang.Exception ex) {
  ex.printStackTrace(System.out);
}
}

}

arg contains the path at which the files is to be stored.

I want that i call the main functions mentioned whenever i want to transfer the file. Basically i want to transfer multiple files which can contain directories as well. to do this I've written the following code.

ServerFile.java

import java.io.*;
import java.net.*;
public class ClientFile implements Runnable{
Socket clientsocket;
public void run() {
    try
    {
        clientsocket = new Socket("219.64.189.14",6789);
    // Some code
    copy(outtoserver,infromserver, files);      // files contains the path of files to be transferred.
    // Some code
        clientsocket.close();
    }
    catch(Exception e2)
    {
            System.out.println("ClientFile   "+String.valueOf(e2) + "\n");
    }
}
public void copy(DataOutputStream outtoserver,BufferedReader infromserver,String[] files)
{
    try
    {
        FileSender fs = new FileSender();
        int totalfiles=0;
        int r=0;
        File oldfile;
        outtoserver.write(files.length);
        String chk;
        while(totalfiles<files.length)
        {

            oldfile = new File(files[totalfiles]);
            if(oldfile.isDirectory())
            {
                outtoserver.writeBytes("folder\n");
                File folder1[] = oldfile.listFiles();
                String[] folder = new String[folder1.length];
                int count=0;
                for(File name : folder1)
                {
                    folder[count] = name + "";
                    System.out.println(folder[count]);
                    count++;
                }
                outtoserver.writeBytes(oldfile.getName()+"\n");
                fs.main(clientsocket, folder);

            }
            else if(oldfile.isFile())
            {
                outtoserver.writeBytes("file\n");
        chk = infromserver.readLine();
                if(chk.equals("send"))
                {
                    outtoserver.writeBytes(oldfile.getName()+"\n");
                    String[] folder = new String[]{oldfile.getAbsolutePath()};
                    fs.main(clientsocket, folder);
                }
                totalfiles++;
                outtoserver.flush();

            }
        }
    }
    catch(Exception e)
    {
        System.out.println("ClientFile -->>  "+e.toString());
    }
}
}

ClientFile.java

import java.io.*;
import java.net.*;
import javax.swing.*;
class ServerFile implements Runnable {
Socket conn;
public ServerFile(Socket a)
{
    conn = a;
}
public void run() {
    File file1;
    String clientsen="";
    try
    {  // Some code
       copy(outtoclient,infromclient,file1.getAbsolutePath());      //file1 is the directory to which the file has to stored.    
   // some code
    }      
    catch(Exception e0)
    {
         System.out.println("ServerFile   "+String.valueOf(e0)+"\n"+e0.getCause());
    }
}//end main
public void copy(DataOutputStream outtoclient,BufferedReader infromclient,String basepath)
{
    try
    {
         FileReceiver fr = new FileReceiver();
         int totfiles = infromclient.read();
         int tot=0;
         File file;
         String path = null,chk;
         while(tot<totfiles)
         {
             chk = infromclient.readLine();
             if(chk.equals("file"))
             {
                outtoclient.writeBytes("send\n");
                path = infromclient.readLine();
                path = basepath+File.separator+path;
                file=new File(path);
                fr.main(conn, basepath+File.separator);
             }
             else if(chk.equals("folder"))
             {
                 String name = infromclient.readLine();
                 name = basepath+File.separator+name;
                 new File(name).mkdir();
                 fr.main(conn, name+File.separator);
             }
             tot++;
         }
    }
    catch(Exception e)
    {
        System.out.println("Server file:    "+e.toString());
    }
}

}//end class

Correct me by all means if I'm wrong.

Any help appreciated.

You send either "file\n" or "folder\n" to the client. To read these strings, you are using a BufferedReader . Pay close attention to the name of that class: Buffered Reader . When you call readLine() on a BufferedReader , it buffers (reads) at least as many bytes as necessary to read the line. It can possibly read more than the exact number of bytes necessary to read the line. For example, suppose the BufferedReader has a buffer size of 256, but your line (including the "\n" ) only requires 8 bytes. This means that the remaining 248 bytes that were buffered will not be read by FileReceiver . It then gets thoroughly confused because it expects a 4-byte integer, but it's actually reading something else.

I recommend you take advantage of the techniques already used in the example. For example, send "file" using:

ByteStream.toStream(os, "file")

And read it using:

ByteStream.toString(in)

so, I don't really understand how does it separate file contents from file name? Probably better create serializable class which contains file name and contents. You can use ObjectInput/OutputStream in this case. Otherwise you need to define some file content/file name separator and use Scanner class to separate files from the input stream.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM