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.