0

I am having issues implementing an Active ftp server using java.

I need a server that will send a file to a client. Wait for the client to send back a response file. (This is a master slave protocol. The client only commincates after it receives a file with a command. )

When I run the code, the files that I get are empty.

my server code.

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.InputStream;

public class ftps {
  public final static int FILE_SIZE=6022386;
  public final static int SOCKET_PORT = 18901;  // you may change this
  public final static String FILE_TO_SEND = "c:/workspace/test/sentfromserver.txt";  // you may change this
  public final static String FILE_TO_RECEIVED="c:/workspace/test/gotfromclient.txt";
  public static void main (String [] args ) throws IOException {
    FileInputStream fis = null;
    BufferedInputStream bis = null;
    OutputStream os = null;
    ServerSocket servsock = null;
    FileOutputStream fos = null;
    BufferedOutputStream bos = null;
    Socket sock = null;
    int bytesRead;
    int current;
    try {
      servsock = new ServerSocket(18901);
      while (true) {
        System.out.println("Waiting...");
        try {
          sock = servsock.accept();
          System.out.println("Accepted connection : " + sock);
          // send file
          File myFile = new File (FILE_TO_SEND);
          byte [] mybytearray  = new byte [(int)myFile.length()];
          fis = new FileInputStream(myFile);
          bis = new BufferedInputStream(fis);
          bis.read(mybytearray,0,mybytearray.length);
          os = sock.getOutputStream();
          System.out.println("Sending " + FILE_TO_SEND + "(" + mybytearray.length + " bytes)");
          os.write(mybytearray,0,mybytearray.length);
          os.flush();
          System.out.println("Done.");
          mybytearray  = new byte [FILE_SIZE];
          InputStream is = sock.getInputStream();
          fos = new FileOutputStream(FILE_TO_RECEIVED);
          bos = new BufferedOutputStream(fos);
          bytesRead = is.read(mybytearray,0,mybytearray.length);
          current = bytesRead;

          do {
             bytesRead =
                is.read(mybytearray, current, (mybytearray.length-current));
             if(bytesRead >= 0) current += bytesRead;
          } while(bytesRead > -1);

          bos.write(mybytearray, 0 , current);
          bos.flush();
          System.out.println("File " + FILE_TO_RECEIVED
              + " downloaded (" + current + " bytes read)");
        }
        finally {
          if (bis != null) bis.close();
          if (os != null) os.close();
          if (sock!=null) sock.close();
          if (bos!=null) bos.close();
        }
      }
    }
    finally {
      if (servsock != null) servsock.close();
    }
  }
}

Client Side

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.InputStream;

public class ftpcc {

     public final static int SOCKET_PORT = 18901;      // you may change this
      public final static String SERVER = "127.0.0.1";  // localhost
      public final static String
           FILE_TO_RECEIVED = "c:/workspace/test/gotfromserver.txt";  // you may change this, I give a
                                                                // different name because i don't want to
                                                                // overwrite the one used by server...
      public final static String FILE_TO_SEND="c:/workspace/test/sentfromclient.txt";
      public final static int FILE_SIZE = 6022386; // file size temporary hard coded
                                                   // should bigger than the file to be downloaded

      public static void main (String [] args ) throws IOException {
        int bytesRead;
        int current = 0;
        FileOutputStream fos = null;
        BufferedOutputStream bos = null;
        FileInputStream fis = null;
        BufferedInputStream bis = null;
        OutputStream os = null;
        Socket sock = null;
        try {
          sock = new Socket(SERVER, 18901);
          System.out.println("Connecting...");

          // receive file
          byte [] mybytearray  = new byte [FILE_SIZE];
          InputStream is = sock.getInputStream();
          fos = new FileOutputStream(FILE_TO_RECEIVED);
          bos = new BufferedOutputStream(fos);
          bytesRead = is.read(mybytearray,0,mybytearray.length);
          current = bytesRead;

          do {
             bytesRead =
                is.read(mybytearray, current, (mybytearray.length-current));
             if(bytesRead >= 0) current += bytesRead;
          } while(bytesRead > -1);

          bos.write(mybytearray, 0 , current);
          bos.flush();
          System.out.println("File " + FILE_TO_RECEIVED
              + " downloaded (" + current + " bytes read)");
          File myFile = new File (FILE_TO_SEND);
          mybytearray  = new byte [(int)myFile.length()];
          fis = new FileInputStream(myFile);
          bis = new BufferedInputStream(fis);
          bis.read(mybytearray,0,mybytearray.length);
          os = sock.getOutputStream();
          System.out.println("Sending " + FILE_TO_SEND + "(" + mybytearray.length + " bytes)");
          os.write(mybytearray,0,mybytearray.length);
          os.flush();
          System.out.println("Done.");
        }
        finally {
          if (fos != null) fos.close();
          if (bos != null) bos.close();
          if (sock != null) sock.close();
          if (bis !=null) bis.close();
        }
      }

    }
JimHawkins
  • 4,843
  • 8
  • 35
  • 55

1 Answers1

1

The InputStream.read(byte[], int, int) method waits for input before returning anything and you've read the entire file before the loop, so both your server and client are stuck in the do..while loops. Remove those and your code will work just fine.

Edit: Check this question for details of how to read the file with a loop.

Konrad Botor
  • 4,765
  • 1
  • 16
  • 26
  • Hi, I have only started java last week so excuse me to this question. Do you mean that I should remove the do while loop. and keep the body as one line? – Terad Alturkistani Jul 16 '18 at 10:09
  • 1
    If your file is smaller than your hardcoded `FILE_SIZE` value then the entire file is read before the `do..while` loop, so the loop is unnecessary. If you file is larger that `FILE_SIZE` it won't fit in `mbytearray` and you'll get exception int the loop. So yes - remove the loop. – Konrad Botor Jul 16 '18 at 10:15
  • Also, if you' re new to Java I'd would suggest looking into some sort of library that can handle file transfers over the network regardless of file sizes rather than writing the code yourself. – Konrad Botor Jul 16 '18 at 10:16
  • My code now work as needed. thanks for the help again. – Terad Alturkistani Jul 16 '18 at 10:26