Click to See Complete Forum and Search --> : Sending a file over Socket


winston2020
April 23rd, 2008, 08:44 AM
Hello, I'm having a really hard time sending a file via a socket. I always end up with just a few bytes short, or a few bytes too many.

Here is the server code:


DataOutputStream out = new DataOutputStream(con.getOutputStream());

File file = new File("N:\\jdk-6u5-windows-i586-p.exe");
BufferedInputStream in = new BufferedInputStream(new FileInputStream(new File("N:\\jdk-6u5-windows-i586-p.exe")));
out.writeLong(in.available());

byte[] buff = new byte[con.getSendBufferSize()];
while(in.available() > 0){

if(in.available() < buff.length){
System.out.println("There are: " + in.available() + " bytes to read.");
System.out.println("Buffere Size is: " + buff.length);

}
out.write(buff);
in.read(buff);

if(in.available() == 0){
try{
System.out.println("Sleeping...");
Thread.sleep(100);
System.out.println("Now: " + in.available());
}catch(Exception e){
System.out.println(e.getMessage());
}
}
}
System.out.println("Server: There are " + in.available() + "bytes available.");

out.flush();
out.close();
in.close();
con.close();


And here's the client:

Socket client = new Socket("localhost", 9370);
DataInputStream sizeIn = new DataInputStream(client.getInputStream());
BufferedInputStream in = new BufferedInputStream(client.getInputStream());
long fileSize = sizeIn.readLong();
long totalBytes = 0;
int progress = 0;
int oldProgress = 0;
System.out.println("FileSize: " + fileSize);

BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(new File("N:\\clientOutput.exe")));
byte[] buff = new byte[client.getReceiveBufferSize()];

//Increment Total Bytes Received
totalBytes += buff.length;

while(in.available() > 0){

in.read(buff);
out.write(buff);
totalBytes += buff.length;



if(in.available() < buff.length){
try{
Thread.sleep(10);
}catch(Exception e){
System.out.println(e.getMessage());
}

//Handle Last Few Bytes
if(in.available() < buff.length && in.available() != 0){
System.out.println("Looping Through Buffer Length");

for(int i = 0; i <= in.available(); i++){
out.write(in.read());
}
}
}

progress = (int)(((float)totalBytes / (float)fileSize) * (float)100);
if(progress != oldProgress){

System.out.println(progress + "%");
oldProgress = progress;
}
}

out.flush();
out.close();


Any Ideas what I'm doing wrong?

keang
April 23rd, 2008, 10:39 AM
I don't understand why you are trying to send a file this way but your problems are down to you using the available() method. If you read the API docs for BufferedInputStream you will see "Returns an estimate of the number of bytes that can be read (or skipped over) from this input stream without blocking by the next invocation of a method for this input stream.". The key word here is 'estimate'. You are basing your loops on the returned value of this method which has nothing to do with how many bytes are actually remaining.

winston2020
April 23rd, 2008, 07:57 PM
I don't understand why you are trying to send a file this way

I have no idea what i'm doing. I'd love for you to tell me the best way to accomplish this :)