Отправка байтового массива с помощью сокета Java - PullRequest
1 голос
/ 19 апреля 2011

Я программирую приложение, которое позволяет загружать PDF-файлы с сервера.На моей серверной стороне я получаю байтовый буфер моего pdf-файла благодаря библиотеке pdfview.Я заполняю байтовые массивы своим байтовым буфером, а затем отправляю байтовые массивы с помощью DataOutputStream.

В большинстве случаев я получаю хорошие данные на стороне клиента, но иногда я получаю массив, заполненный случайными числами ипоэтому я не могу восстановить свой файл PDF.У меня обычно возникает следующая ошибка: «java.io.IOException: это может быть не файл PDF»

Так что, когда я сравниваю полученные данные с отправленными данными, это совершенно другое.Я могу заметить, что данные в серверной части всегда верны

Любая помощь приветствуется

//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();
  }

1 Ответ

1 голос
/ 19 апреля 2011
this.in = new ObjectInputStream(this.socket.getInputStream());
this.out = new DataOutputStream(this.socket.getOutputStream());
this.outObject = new ObjectOutputStream(this.socket.getOutputStream());

Вам не нужен DataOutputStream здесь, и вы должны создать ObjectOutputStream до ObjectInputStream, в противном случае вы получите тупик.

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

Bzzt.Если следующий объект является строкой, эта строка кода будет работать, но она должна была использовать приведение (String), а не toString ().Если следующий объект не a String, вы только что испортили его во что-то еще.

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

Бессмысленно.(а) он уже был полон нулей, и (б) если вы настаиваете на втором назначении, в чем смысл первого назначения?

Остальная часть вашего кода является многословным и, вероятно, ошибочным способомотправки файла в сокет.Вот простой способ:

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.
...