David Kosub
David Kosub

Reputation: 53

ServerSocket File Transmission Missing Bytes

Issue

I have confirmed via a packet sniffer that all data coming from the client is being totally sent, and that the data being received by the server is complete as well, however there is a slight problem.

Here is a basic representation of relevant parts of the client thread within the server.

this.data_in = new DataInputStream(sock.getInputStream());
this.in = new InputStreamReader(this.data_in);

The server will read in authentication data using the BufferedReader, and once authentication is complete it will read data from the socket, like so. The variable 'fos' is a FileOutputStream that the DataInputStream data is being written to.

int read = 0;
byte[] buffer = new byte[8192];
while((read = data_in.read(buffer)) != -1) {
    fos.write(buffer, 0, read);
    bytes_received += read;
}

This all seems correct in concept, however, in practice the first 1450 bytes of the file read in are missing. I have tried using a new DataInputStream(sock.getInputStream()) in case the position in the stream was weird but still no luck. Thanks for any help!

Update 1

So I could use BufferedReader functionality I made a method to read in string lines as I was using them before. See below code.

int input;
boolean run = true;
while((input = in.read()) != -1 && run) {
    run = true;
    char[] chars = Character.toChars(input);
    for(char c : chars) {
        if(c == '\n') {
            run = false;
            break;
        } else if(c != '\r') {
            sb.append(c);
        }
    }
}

As great of a solution it seemed, there is still 1450 bytes of information missing. Maybe I'm going in the wrong direction here?

Upvotes: 1

Views: 796

Answers (2)

Yahia
Yahia

Reputation: 70379

To me it looks like the BufferedReader is the problem - according to http://ulibgcj.sourceforge.net/javadoc/java/io/BufferedReader.html is has default buffer size of 8192... whatever this default buffer size is in your case, the BufferedReader will advance the data_in in steps of that default buffer size... so even if you don't consume them data_in is usually on a position beyond the last bytes you consumed during authentication.

Upvotes: 1

Ryan Stewart
Ryan Stewart

Reputation: 128919

You seem to be keeping two separate stream/readers that refer to the same thing: this.data_in and this.in. Reading from either will advance the stream, and then reads from the other will appear to "miss" the data that was read in the other. Also, you're using the DataInputStream just like a regular old InputStream by using the read(byte[]) method. DataInputStream is a specialized stream with a specific purpose.

Upvotes: 1

Related Questions