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.
There is a typo in private void sendMessage(String message): It always sends “request” instead of “message”.
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?
Thanks a lot for providing this code
is there any mistake in both sender and receiver code in while loop…
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
its the greater than symbol. `>` is encoded as > in HTML
hey you guyz saved my day.
Take a look at my own API –>
> symbol is encoded sometimes to > by URI Encoding.