2

Receiving files on socket

 2 years ago
source link: https://www.codesd.com/item/receiving-files-on-socket.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Receiving files on socket

advertisements

I am implementing a Direct Connect client. I am using the NMDC protocol. I can connect to a hub and other connected clients. I am trying to retrieve the file list from each client, I understand that in order to do that one must download the file files.xml.bz2 from the other client. The protocol to download a file is as follows:

  ->   $ADCGET file <filename> <params>|
  <-   $ADCSND file <fileName> <params>|
  <-   (*** binary data is now transfered from client B to client A ***)

I am trying to create a file named files.xml.bz2 using the binary data received. Here's my code:

//filesize is provided through the $ADCSND response from other client
byte[] data = new byte[filesize];
/*

Reading binary data from socket inputstream

*/
int read = 0;
for (int i=0; read<filesize;){
    int available = in2.available();
    int leftspace = filesize-read;
    if (available>0){
        in2.read(data, read, available>leftspace? leftspace:available);
        ++i;
    }
    read += (available>leftspace? leftspace:available)+1;
}
/*
writing the bytes to an actual file
*/
ByteArrayInputStream f = new ByteArrayInputStream(data);
FileOutputStream file = new FileOutputStream("files.xml.bz2");
file.write(data);
file.close();

The file is created, however, the contents (files.xml) are not readable. Opening it in firefox gives:

XML Parsing Error: not well-formed

Viewing the contents in the terminal only reads binary data. What am i doing wrong?

EDIT

I also tried Decompressing the file using the bz2 libray from Apache Ant.

ByteArrayInputStream f = new ByteArrayInputStream(data);
BZip2CompressorInputStream bzstream = new BZip2CompressorInputStream(f);
FileOutputStream xmlFile = new FileOutputStream("files.xml");
byte[] bytes = new byte[1024];
while((bzstream.read(bytes))!=-1){
    xmlFile.write(bytes);
}
xmlFile.close();
bzstream.close();

I get an error, here's the stacktrace:

java.io.IOException: Stream is not in the BZip2 format
    at org.apache.commons.compress.compressors.bzip2.BZip2CompressorInputStream.init(BZip2CompressorInputStream.java:240)
    at org.apache.commons.compress.compressors.bzip2.BZip2CompressorInputStream.<init>(BZip2CompressorInputStream.java:132)
    at org.apache.commons.compress.compressors.bzip2.BZip2CompressorInputStream.<init>(BZip2CompressorInputStream.java:109)
    at control.Controller$1.run(Controller.java:196)


Usual, typical misuse of available(). All you need to copy a stream in Java is as follows:

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

Use this with any size buffer greater than zero, but preferably several kilobytes. You don't need a new buffer per iteration, and you don't need to know how much data is available to read without blocking, as you have to block, otherwise you're just smoking the CPU. But you do need to know how much data was actually read per iteration, and this is the first place where your code falls down.


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK