Java Socket Programming-Transferring large sized files through socket

So far we have discussed the fundamentals of Socket programming . In a previous chapter we have discussed the file transfer using TCP. In that example we were converting the entire file object into byte array . And sending it through the socket.But that cannot be applied to large sized file.Because the heap of a JVM  cannot afford an object beyond its maximum capacity.So for transferring large sized files we need to use another approach. In this chapter we are discussing about  transferring large sized files through socket with suitable example.The file size does not have any limit in this case.So this application can be used to transfer movies of large or very large size.The java nio package has a SocketChannel component.We can use a  SocketChannel instance for  sending file. On the other side of connection , a ServerSocketChannel  accepts the connection.Read/Write operations  on a file is done with FileChannel instances

Transferring large sized files through socket

FileSender.java

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.SocketChannel;

public class FileSender {
public static void main(String[] args) {
FileSender nioClient = new FileSender();
SocketChannel socketChannel = nioClient.createChannel();
nioClient.sendFile(socketChannel);

}

/**
* Establishes a socket channel connection
*
* @return
*/
public SocketChannel createChannel() {

SocketChannel socketChannel = null;
try {
socketChannel = SocketChannel.open();
SocketAddress socketAddress = new InetSocketAddress("localhost", 9999);
socketChannel.connect(socketAddress);
System.out.println("Connected..Now sending the file");

} catch (IOException e) {
e.printStackTrace();
}
return socketChannel;
}


public void sendFile(SocketChannel socketChannel) {
RandomAccessFile aFile = null;
try {
File file = new File("D:\\Test\\Video.avi");
aFile = new RandomAccessFile(file, "r");
FileChannel inChannel = aFile.getChannel();
ByteBuffer buffer = ByteBuffer.allocate(1024);
while (inChannel.read(buffer) > 0) {
buffer.flip();
socketChannel.write(buffer);
buffer.clear();
}
Thread.sleep(1000);
System.out.println("End of file reached..");
socketChannel.close();
aFile.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}

}

}

FileReceiver.java

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;


public class FileReceiver {

public static void main(String[] args) {
FileReceiver nioServer = new FileReceiver();
SocketChannel socketChannel = nioServer.createServerSocketChannel();
nioServer.readFileFromSocket(socketChannel);
}

public SocketChannel createServerSocketChannel() {

ServerSocketChannel serverSocketChannel = null;
SocketChannel socketChannel = null;
try {
serverSocketChannel = ServerSocketChannel.open();
serverSocketChannel.socket().bind(new InetSocketAddress(9999));
socketChannel = serverSocketChannel.accept();
System.out.println("Connection established...." + socketChannel.getRemoteAddress());

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

return socketChannel;
}

/**
* Reads the bytes from socket and writes to file
*
* @param socketChannel
*/
public void readFileFromSocket(SocketChannel socketChannel) {
RandomAccessFile aFile = null;
try {
aFile = new RandomAccessFile("E:\\Test\\Video.avi", "rw");
ByteBuffer buffer = ByteBuffer.allocate(1024);
FileChannel fileChannel = aFile.getChannel();
while (socketChannel.read(buffer) > 0) {
buffer.flip();
fileChannel.write(buffer);
buffer.clear();
}
Thread.sleep(1000);
fileChannel.close();
System.out.println("End of file reached..Closing channel");
socketChannel.close();

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

}
}

Output

Specify a valid file as source file in FileSender.java .Specify a valid and existing output folder at the FileReceiver.java  while initializing the RandomAccessFile object.In the above code , we used  localHost  as address .We need to put suitable address there. Start the FileReceiver.java and then FileSender.java.The file would be sent from source to destination.  These applications can be used to transfer large sized files (like .mkv  , .mprg movies) from one machine to another.This application can be used to transfer files of  all formats.

9 thoughts on “Java Socket Programming-Transferring large sized files through socket

  1. Aaron Digulla Reply

    There is a typo in private void sendMessage(String message): It always sends “request” instead of “message”.

  2. Keshav Reply

    Above program works well if the data is not huge say 20 mb or so. But I tried to move a movie and even though the file size is correct on the client but there is some data corruption.

    How can we enhance the client server to check for data corruption?

    • sai sandeep Reply

      Yes, think you have to replace the line in the ( ) for while with (inchannel.read(buffer) > 0 ) in the file sender and correspondingly in the file receiver program

Leave a Reply

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