5

I am trying to send a file from one computer to another using Java. I have written the code below, it works fine if both sender and receiver are started in the same computer but if they work on different machines received file size is bigger than the original file and it is corrupted.

Note: I am trying to transfer files which are max 10 MBs.

How can I fix this?

Sender:

ServerSocket server_socket = new ServerSocket(8989);
File myFile = new File(myPath);

Socket socket = server_socket.accept();
int count;
byte[] buffer = new byte[1024];

OutputStream out = socket.getOutputStream();
BufferedInputStream in = new BufferedInputStream(new FileInputStream(myFile));
while ((count = in.read(buffer)) > 0) {
     out.write(buffer, 0, count);
     out.flush();
}
socket.close();

Receiver:

Socket socket = new Socket(address, 8989);
FileOutputStream fos = new FileOutputStream(anotherPath);
BufferedOutputStream out = new BufferedOutputStream(fos);
byte[] buffer = new byte[1024];
int count;
InputStream in = socket.getInputStream();
while((count=in.read(buffer)) >0){
    fos.write(buffer);
}
fos.close();
socket.close();
1
  • i have used this funtion for sending and and recieving file but i dont want to close the socket as i have to perform some other function using the socket but if i dont close the sock file recieving isn't get complete whats the soluion for that Commented May 9, 2016 at 11:59

3 Answers 3

23

On the client side you write up to count bytes and send them:

while ((count = in.read(buffer)) > 0) {
  out.write(buffer, 0, count);

on the server side you read up to count bytes - but then you write the whole buffer to file!

while((count=in.read(buffer)) > 0){
  fos.write(buffer);

Just change it to:

fos.write(buffer, 0, count);

and you'll be on the safe side. BTW your program has another small bug: read() can return 0 which doesn't mean InputStream ended. Use >= instead:

count = in.read(buffer)) >= 0

Have you considered IOUtils.copy(InputStream, OutputStream) from Apache Commons? It would reduce your whole while loops to:

OutputStream out = socket.getOutputStream();
InputStream in = new FileInputStream(myFile);
IOUtils.copy(in, out);
socket.close();

Less code to write, less code to test. And buffering is done internally.

Sign up to request clarification or add additional context in comments.

1 Comment

@Vamshi. if you are using IOUtils then yes because it implements its own buffering.
3

Remember that in.read(buffer) not necessarily fills up the whole buffer with new data. Therefore you should make sure you don't write the whole buffer. Change

while((count=in.read(buffer)) >0){
    fos.write(buffer);
}

to

while((count=in.read(buffer)) >0){
    fos.write(buffer, 0, count);
}

Comments

1

sender

Socket sock = new Socket("127.0.0.1", 5991);
        System.out.println("Connecting.........");
        File myFile = new File("/root/qrcode/");
        File[] files = myFile.listFiles();
       OutputStream os = sock.getOutputStream();
        BufferedOutputStream bos = new BufferedOutputStream(os);
                            DataOutputStream dos = new DataOutputStream(bos);

                            dos.writeInt(files.length);
                            long totalBytesRead = 0;
                            int percentCompleted = 0;
                            for(File file : files)
                            {
                                     long length = file.length();
                                     dos.writeLong(length);

                                     String name = file.getName();
                                     dos.writeUTF(name);

                                     FileInputStream fis = new FileInputStream(file);
                                     BufferedInputStream bis = new BufferedInputStream(fis);

                                     int theByte = 0;
                                     while((theByte = bis.read()) != -1)
                                     {
                                        totalBytesRead += theByte;


                                        bos.write(theByte);
                                     }
                                    //  System.out.println("file read");
                                     bis.close();
                                 }

                                dos.close();


        //Closing socket  
        sock.close();

receiver

ServerSocket serverSocket = new ServerSocket(5991);  

    while(true) {  
        Socket clientSocket = null; 
        System.out.println("Starting...");
        clientSocket = serverSocket.accept();  

        InputStream in = clientSocket.getInputStream(); //used

        BufferedInputStream bis = new BufferedInputStream(in);

        String dirPath  ;
        dirPath = "/root/NewFolder";

        try{
            DataInputStream dis = new DataInputStream(bis);

            int filesCount = dis.readInt();
            File[] files = new File[filesCount];
            long f_l = 0;
            int count =0 ;
            long totalBytesRead = 0;
            int percentCompleted = 0;

            for(int i = 0; i < filesCount; i++)
            {
                long fileLength = dis.readLong();
                String fileName = dis.readUTF();

                f_l = f_l +fileLength;
                files[i] = new File(dirPath + "/" + fileName);

                FileOutputStream fos = new FileOutputStream(files[i]);
                BufferedOutputStream bos = new BufferedOutputStream(fos);

                int tot = 0;
                for(int j = 0; j < fileLength; j++) {

                    bos.write(bis.read());
                }

                bos.close();

            }

        }catch(Exception ex)
        {
            System.out.println("error in socket programming ");
        }
    }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.