Cedric
Cedric

Reputation: 21

Sending a byte array with Java socket

I am programming an application which allows to download pdf files from a server. In my server side, I get a bytebuffer of my pdf file thanks to the pdfview library. I fill byte arrays with my byte buffer and then I send the byte arrays with a DataOutputStream.

Most of the time, I get good data in my client side, but sometimes I get an array filled with random numbers and so I can't rebuild my pdf file. I usually have the following error : "java.io.IOException: This may not be a PDF File"

So When I compare received data with sent data, it is totally different. I can noticed that data in the server part are always correct

Any help is appreciated

//Server side
this.in = new ObjectInputStream(this.socket.getInputStream());
this.out = new DataOutputStream(this.socket.getOutputStream()); 
this.outObject = new ObjectOutputStream(this.socket.getOutputStream());

this.res = this.in.readObject().toString();//I read the client order(GET home page, next page...)

//I get the bytebuffer from the pdf file------
this.file = new File (name+this.numFile+".pdf");
RandomAccessFile raf;
raf = new RandomAccessFile(this.file, "r");
FileChannel channel = raf.getChannel();
this.buf = channel.map(FileChannel.MapMode.READ_ONLY,0, channel.size());
//--------------------------------------------

int size = this.buf.capacity();
this.out.writeInt(size);//I send the size of my bytebuffer to the server

int size_array = 1000;
this.pack = new byte[size_array];
this.pack = clean_array();//I replace my variable by an array filled with zeros

for(long i=0;i<(size/size_array);i++){
buf.get(this.pack);
    this.out.write(this.pack);
    this.pack = clean_array();//I replace my variable by an array filled with zeros
}

//I have not sent the whole bytebuffer, the last byte array could have a different size
//I work out this size, I create the new bytearray and I send it---------------------
int byteLeft = size%size_array;
if(byteLeft>0){
    this.pack = new byte[byteLeft];
buf.get(this.pack);
this.out.write(this.pack);
this.pack = clean_array();//I replace my variable by an array filled with zeros
}

 //-------------------------------------------------

//Client side
int size_array = 1000;

pack =new byte[size_array];
pack = clean_array();

for(int i=0;i<((size/size_array));i++){     
    in.read(pack);
    buf.put(pack);
        pack = clean_array();
}

if(size%size_array>0){
//for the last loop, the number of bytes sent by the server is not equal to 1000
//So I create a byte array with the good size
   pack = new byte[size%size_array];
   in.read(pack);
   buf.put(pack);
   pack = clean_array();
  }

Upvotes: 1

Views: 5871

Answers (1)

user207421
user207421

Reputation: 310913

this.in = new ObjectInputStream(this.socket.getInputStream());
this.out = new DataOutputStream(this.socket.getOutputStream());
this.outObject = new ObjectOutputStream(this.socket.getOutputStream());

You don't need the DataOutputStream here, and you must create the ObjectOutputStream before the ObjectInputStream, otherwise you get a deadlock.

this.res = this.in.readObject().toString();//I read the client order(GET home page, next page...)

Bzzt. If the next object is a String this line of code will work, but it should have used a (String) cast, not toString(). If the next object isn't a String you have just corrupted it into something else.

this.pack = new byte[size_array];
this.pack = clean_array();//I replace my variable by an array filled with zeros

Pointless. (a) it already was full of zeros, and (b) if you insist on the second assignment what is the point of the first assignment?

The rest of your code is a long-winded and probably erroneous way of sending a file to the socket. Here's the easy way:

FileInputStream fin = new FileInputStream(file);
int count;
byte[] buffer = new byte[8192];
while ((count = fin.read(buffer)) > 0)
  out.write(buffer, 0, count);  // here 'out' is the socket output stream or whatever you want to wrap around it.

Upvotes: 1

Related Questions