Java Socket Programming-File transfer through socket in Java

So far we have discussed  the fundamental concepts of networking with Java . We also discussed the  TCP and UDP modes of communication in Java with suitable examples.In previous chapters we were discussing a chat application in java  and file transfer in Java using socket programming . But the file transfer example we discussed was not a standard one.In this chapter we are discussing a more enhanced version of the file transfer through socket in java  example we discussed earlier.(File transfer can be done using UDP too. It is explained already with good example .Please see the post)

File transfer through socket in Java

Our application has a client and a server.  Our aim is to send a file from the client machine to the server machine. In this case, we are sending the file as a java object.(We already discussed the way to transfer java objects through sockets before) . The object contains the file name , destination path , file content ,status of transfer etc. Lets see the FileEvent.java .We  are sending the file  with  details as attributes of object of this class.

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;

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;
}
}

Now lets see the server code.It simply creates a ServerSocket on port 4445 and waiting for incoming socket connections.Once a connection comes , it accepts the connection.And then it is reading the FileEvent object. Destination directory , file etc are creating. Data is writing to the output file too. Then closing and exiting.

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

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 downloadFile() {
try {
fileEvent = (FileEvent) inputStream.readObject();
if (fileEvent.getStatus().equalsIgnoreCase("Error")) {
System.out.println("Error occurred ..So exiting");
System.exit(0);
}
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 ");
Thread.sleep(3000);
System.exit(0);

} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}

public static void main(String[] args) {
Server server = new Server();
server.doConnect();
server.downloadFile();
}
}

Now see the client code.It simply requests for a socket connection .After getting connection, it is creating the FileEvent object which contains the file details along with full content as byte stream.Then writing the FileEvent object to socket and exiting itself.

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

public class Client {
private Socket socket = null;
private ObjectOutputStream outputStream = null;
private boolean isConnected = false;
private String sourceFilePath = "E:/temp/songs/song1.mp3";
private FileEvent fileEvent = null;
private String destinationPath = "C:/tmp/downloads/";

public Client() {

}

/**
* Connect with server code running in local host or in any other host
*/
public void connect() {
while (!isConnected) {
try {
socket = new Socket("localHost", 4445);
outputStream = new ObjectOutputStream(socket.getOutputStream());
isConnected = true;
} catch (IOException e) {
e.printStackTrace();
}
}
}

/**
* Sending FileEvent object.
*/
public void sendFile() {
fileEvent = new FileEvent();
String fileName = sourceFilePath.substring(sourceFilePath.lastIndexOf("/") + 1, sourceFilePath.length());
String path = sourceFilePath.substring(0, sourceFilePath.lastIndexOf("/") + 1);
fileEvent.setDestinationDirectory(destinationPath);
fileEvent.setFilename(fileName);
fileEvent.setSourceDirectory(sourceFilePath);
File file = new File(sourceFilePath);
if (file.isFile()) {
try {
DataInputStream 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.setFileSize(len);
fileEvent.setFileData(fileBytes);
fileEvent.setStatus("Success");
} catch (Exception e) {
e.printStackTrace();
fileEvent.setStatus("Error");
}
} else {
System.out.println("path specified is not pointing to a file");
fileEvent.setStatus("Error");
}
//Now writing the FileEvent object to socket
try {
outputStream.writeObject(fileEvent);
System.out.println("Done...Going to exit");
Thread.sleep(3000);
System.exit(0);
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}

}

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

If connection is between two different computers , then in place of local host ,ip address of machine in which server is running needs to be given .

Output

The source file is E:/temp/songs/song1.mp3 . After running both Client and Server , the song1.mp3 will be there in C:/tmp/downloads/  in the machine where server is running.

Remember, this application cannot be used to transfer file of very huge size (say 300 MB or above). The maximum size of file that can be transferred  depends on the capacity of JVM using.

See also:

Basics of socket programming

Communication using TCP

Communication using UDP

Chat application in Java using socket programming

Transferring Java objects through sockets

20 thoughts on “Java Socket Programming-File transfer through socket in Java

  1. Sergiu Reply

    Hi there, I would like to ask you a question regarding this file transfer program if I may. Can you please email me your email so I can ask you directly?

    Thanks a lot.

    Regards,
    Sergiu

  2. Jane Loo Reply

    Hi, Thanks for the code!
    I’m currently implementing it into my school project. However I have some problem at the server side. I have sent the fileEvent object throught objectoutputstream to my server.
    However, in this line of code of server : fileEvent = (FileEvent) input.readObject();
    I got an error which is ClassNotFoundException.

    I’ll be glad if some help is provided.
    Thanks

      • Cambodia Raven Reply

        build Class FileEvent to jar file and add into library in project client and project Server

  3. ubs Reply

    Hi I am having a similar error in this line of code of server : fileEvent = (FileEvent) input.readObject();
    I got an error which is ClassNotFoundException.
    please kindly help me asap i have to make it as a school project.

    • Bijoy Post authorReply

      Hello..Please ensure that the the FileEvent.java is compiled and is in a suitable package.

      Thank you

      • roxy Reply

        please explain in details ? Do i need to put file fileEvent.java in both project

        • Bijoy Post authorReply

          Yes.Since we are sending the file as a serialized FileEvent object , FileEvent.java should be there at both client and server sides.

          Thank you

  4. Amar Gangwar Reply

    I have one question is that both socket and server programs should run in different machines or on same.

    • Bijoy Post authorReply

      We can run in both ways.The only thing we need to change is the ip address.Instead of giving localhost , we should give the correct ip address

  5. Margherita Reply

    Hi, I have a problem that I can’t solve and it’s important for me your answer..
    When I run my Server, it marks me as a mistake java.lang.ClassNotFoundException (and the class is MAIN class).
    It’s difficult to understand what’s wrong.. Hope you read this, and you’ll answer me soon.
    Even the Classpath is a problem that I don’t understand to solve…
    Thanks.

  6. Majk Reply

    To everybody still struggling with the ClassNotFoundException :
    you have to place the FileEvent class in different package and add these packages to both client and server application.

  7. Wenping Zou Reply

    Hi 🙂
    It works well.Thanks a lot!

    I also went across the error upstairs.
    I exported the FileEvent as jar file;
    Then added it both to Server.class and Client.class.
    It worked !(Hope this may help others)

    Thanks again!!

  8. Saqi Reply

    Hi, can you please let me know why server is close after receive the request, even i remove System.exit(0) from both client and server. I need server should not close and keep running what i should change, Please help.

  9. Susmith Surendra Reply

    Hii… It’s working Better…! Thanks a lot for did it for us. But I have small problem, what it is if you ask that i could not able to transfer the files in between two computers through using IP address. First i thought it might Firewall problem, then i clear it. But after that only getting same error like..,,,

    java.net.ConnectException: Connection refused
    at java.net.PlainSocketImpl.socketConnect(Native Method)
    at java.net.AbstractPlainSocketImpl.doConnect (AbstractPlainSocketImpl.java:339)
    at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:200)
    at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:182)
    at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
    at java.net.Socket.connect(Socket.java:579)
    at java.net.Socket.connect(Socket.java:528)
    at java.net.Socket.(Socket.java:425)
    at java.net.Socket.(Socket.java:208)
    at Client.connect(Client.java:22)
    at Client.main(Client.java:79)

  10. Ryan Moore Reply

    Thanks for sharing your thoughts! There are, however, some
    pitfalls when it comes to clinic. Once I was a school student, I thought how one should tackle this matter but I’d
    constantly come across some questionable responses: go google
    it or ask for a friend. What if my friends do not have
    enough knowledge or expertise to help me? Imagine if I googled it several times and couldn’t
    find the solution? That’s when articles like this you can provide proper guidance
    on the matter. Once more, thank you for the job!

Leave a Reply

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