Java Socket programming-Transferring directory through socket in Java

So far we have discussed the fundamentals of Java networking .We also discussed about TCP and UDP methods of communication.In the previous chapter we have seen how to transfer a file between two machines in a network through TCP Socket. In this chapter we are discussing how transferring the contents of  directory or folder  through socket in Java  is possible.

Transferring directory through socket in Java – example

We have a client and a server applications.The directory is transferring from client to server. The client scans the source directory for individual files. It sends each file as an object . The object also contains the details of file like  file name , file size etc.The server receives each object and it is creating  and writing those files in the specified destination directory. Let us examine the FileEvent.java whose object contains the file along with the necessary metadata related with that file.The client sends the objects of FileEvent to server.

FileEvent.java

import java.io.Serializable;

public class FileEvent implements Serializable {

public FileEvent() {
}

private static final long serialVersionUID = 1L;

private String destinationDirectory;
private String sourceDirectory;
private String filename;
private long fileSize;
private byte[] fileData;
private String status;
private int remainder;

public String getDestinationDirectory() {
return destinationDirectory;
}

public void setDestinationDirectory(String destinationDirectory) {
this.destinationDirectory = destinationDirectory;
}

public String getSourceDirectory() {
return sourceDirectory;
}

public void setSourceDirectory(String sourceDirectory) {
this.sourceDirectory = sourceDirectory;
}

public String getFilename() {
return filename;
}

public void setFilename(String filename) {
this.filename = filename;
}

public long getFileSize() {
return fileSize;
}

public void setFileSize(long fileSize) {
this.fileSize = fileSize;
}

public String getStatus() {
return status;
}

public void setStatus(String status) {
this.status = status;
}

public byte[] getFileData() {
return fileData;
}

public void setFileData(byte[] fileData) {
this.fileData = fileData;
}

public int getRemainder() {
return remainder;
}

public void setRemainder(int remainder) {
this.remainder = remainder;
}
}

The FileEvent.java should implement the Serializable interface.The reason is explained in an earlier chapter.

Now lets see the Server.java.It is accepting socket connection from client. And after getting connected , it is receving FileEvent objects continuously till the last file is received.(The FileEvent object of last file has remainder attribute value as zero).After receiving all files  the server exits itself.

import java.net.ServerSocket;
import java.net.Socket;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;

public class Server {
private ServerSocket serverSocket = null;
private Socket socket = null;
private ObjectInputStream inputStream = null;
private FileEvent fileEvent;
private File dstFile = null;
private FileOutputStream fileOutputStream = null;

public Server() {

}

/**
* Accepts socket connection
*/
public void doConnect() {
try {
serverSocket = new ServerSocket(4445);
socket = serverSocket.accept();
inputStream = new ObjectInputStream(socket.getInputStream());
} catch (IOException e) {
e.printStackTrace();
}
}

/**
* Reading the FileEvent object and copying the file to disk.
*/
public void downloadFiles() {
while (socket.isConnected()) {
try {
fileEvent = (FileEvent) inputStream.readObject();
if (fileEvent.getStatus().equalsIgnoreCase("Error")) {
System.out.println("Error occurred ..with file" + fileEvent.getFilename() + "at sending end ..");

}
String outputFile = fileEvent.getDestinationDirectory() + fileEvent.getFilename();
if (!new File(fileEvent.getDestinationDirectory()).exists()) {
new File(fileEvent.getDestinationDirectory()).mkdirs();
}
dstFile = new File(outputFile);
fileOutputStream = new FileOutputStream(dstFile);
fileOutputStream.write(fileEvent.getFileData());
fileOutputStream.flush();
fileOutputStream.close();
System.out.println("Output file : " + outputFile + " is successfully saved ");
if (fileEvent.getRemainder() == 0) {
System.out.println("Whole directory is copied...So system is going to exit");
System.exit(0);
}

} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
Server server = new Server();
server.doConnect();
server.downloadFiles();
}
}

Now its the time to see the client application.It is   connecting to server.And creating FileEvent objects for each file in the source directory and sending to server application.The source path destination path , host name etc are specific to each need.

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

public class Client {
private Socket socket = null;
private boolean isConnected = false;
private ObjectOutputStream outputStream = null;
private String sourceDirectory = "E:/temp/songs";
private String destinationDirectory = "C:/tmp/downloads/";
private int fileCount = 0;
private FileEvent fileEvent = null;

public Client() {

}

public void connect() {
while (!isConnected) {
try {
socket = new Socket("localHost", 4445);
outputStream = new ObjectOutputStream(socket.getOutputStream());
isConnected = true;
} catch (IOException e) {
e.printStackTrace();
}
}
}

public void locateFiles() {
File srcDir = new File(sourceDirectory);
if (!srcDir.isDirectory()) {
System.out.println("Source directory is not valid ..Exiting the client");
System.exit(0);
}
File[] files = srcDir.listFiles();
fileCount = files.length;
if (fileCount == 0) {
System.out.println("Empty directory ..Exiting the client");
System.exit(0);
}

for (int i = 0; i < fileCount; i++) { System.out.println("Sending " + files[i].getAbsolutePath()); sendFile(files[i].getAbsolutePath(), fileCount - i - 1); System.out.println(files[i].getAbsolutePath()); } } public void sendFile(String fileName, int index) { fileEvent = new FileEvent(); fileEvent.setDestinationDirectory(destinationDirectory); fileEvent.setSourceDirectory(sourceDirectory); File file = new File(fileName); fileEvent.setFilename(file.getName()); fileEvent.setRemainder(index); DataInputStream diStream = null; try { diStream = new DataInputStream(new FileInputStream(file)); long len = (int) file.length(); byte[] fileBytes = new byte[(int) len]; int read = 0; int numRead = 0; while (read < fileBytes.length && (numRead = diStream.read(fileBytes, read, fileBytes.length - read)) >= 0) {
read = read + numRead;
}
fileEvent.setFileData(fileBytes);
fileEvent.setStatus("Success");
} catch (Exception e) {
e.printStackTrace();
fileEvent.setStatus("Error");

}

try {
outputStream.writeObject(fileEvent);
} catch (IOException e) {
e.printStackTrace();
}
}

public static void main(String[] args) {
Client client = new Client();
client.connect();
client.locateFiles();
}
}

Output

Run both client and server after giving correct source directory , destination directory and host address in client application.The status will be displayed in console for both the applications.When the transfer completes both applications exits.

See also:

Networking in Java -Overview

TCP communication in Java

UDP communication in Java

Chat application in Java using socket programming

Transferring Java object through socket

Transferring file through socket

8 thoughts on “Java Socket programming-Transferring directory through socket in Java

  1. Rahul Reply

    I am getting belor error on running this

    java.net.SocketException: Connection reset
    at java.net.SocketInputStream.read(Unknown Source)
    at java.net.SocketInputStream.read(Unknown Source)
    at java.io.ObjectInputStream$PeekInputStream.peek(Unknown Source)
    at java.io.ObjectInputStream$BlockDataInputStream.peek(Unknown Source)
    at java.io.ObjectInputStream$BlockDataInputStream.peekByte(Unknown Source)
    at java.io.ObjectInputStream.readObject0(Unknown Source)
    at java.io.ObjectInputStream.readObject(Unknown Source)
    at test2.Server.downloadFiles(Server.java:42)
    at test2.Server.main(Server.java:72)

    • Rahul Reply

      line fileEvent = (FileEvent) inputStream.readObject(); is throwing error

      java.net.SocketException: Connection reset
      at java.net.SocketInputStream.read(Unknown Source)
      at java.net.SocketInputStream.read(Unknown Source)
      at java.io.ObjectInputStream$PeekInputStream.peek(Unknown Source)
      at java.io.ObjectInputStream$BlockDataInputStream.peek(Unknown Source)
      at java.io.ObjectInputStream$BlockDataInputStream.peekByte(Unknown Source)
      at java.io.ObjectInputStream.readObject0(Unknown Source)
      at java.io.ObjectInputStream.readObject(Unknown Source)
      at test2.Server.downloadFiles(Server.java:42)
      at test2.Server.main(Server.java:72)

      • Bijoy Post authorReply

        Rahul,
        Please check the client side too.If we give wrong directory path at the client side , the client will close the socket connection.So please check the console of Client.java

          • Bijoy Post author

            Rahul,
            Are you getting anything in the client side console ?

  2. ajay prakash tamta Reply

    Hello Sir,
    how can we transfer files from multiple clients to single server.

Leave a Reply

Your email address will not be published. Required fields are marked *