Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

java send file using sockets

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();
like image 514
b4da Avatar asked Nov 25 '12 21:11

b4da


1 Answers

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.

like image 70
Tomasz Nurkiewicz Avatar answered Sep 30 '22 23:09

Tomasz Nurkiewicz