3

I am using a filechannel with a byte buffer to send packets over the network. My problem is that when the filechannel reads the last few bytes it appends the last bit of data from previous bytes read even though I am clearing the byte buffer after I write.

For example,

Byte Buffer size = 512 For the last iteration, the remaining bytes to send is 372. It reads the last 372 but it also appends another 140 bytes (512-372) to the end of it, and appears that last 140 bytes is from the previous 512 bytes sent.

Heres my code:

ByteBuffer bBuffer = ByteBuffer.allocate(512);

while (fChannel.read(bBuffer) > 0) {

    bBuffer.flip();
    datagramChannel.write(bBuffer);
    bBuffer.clear();

    //omitted code
}
user3339242
  • 631
  • 2
  • 15
  • 32
  • @Fildor So is there another way to handle this situation, without clear – user3339242 Nov 17 '14 at 20:30
  • this code looks correct. my guess is the bug lies elsewhere. are you getting the extra bytes in the datagram consumer? if so, show your consumer code. – jtahlborn Nov 17 '14 at 20:35
  • @Fildor - ByteBuffers contain all that info, you don't need to do that (and in fact, there is no such method). – jtahlborn Nov 17 '14 at 20:42
  • @Fildor I was thinking I could set a value equal to fChannel.read(bBuffer) then create a byte buffer with that particular size and set it equal to my old byte buffer – user3339242 Nov 17 '14 at 20:46
  • 1
    @user3339242 - you would be wasting your time with that. can you answer the question in my first comment? – jtahlborn Nov 17 '14 at 20:47
  • @jtahlborn On the receiving side it says it is receiving 372 bytes which is what I expect – user3339242 Nov 17 '14 at 20:49
  • 2
    then i am confused as to where you are seeing the "extra" bytes? – jtahlborn Nov 17 '14 at 20:50
  • @jtahlborn it says it receives the correct number of bytes but the data in the text file repeats at the end – user3339242 Nov 17 '14 at 20:55
  • 1
    _what_ text file? again, if this is the consumer side, then you should _show that code_. – jtahlborn Nov 17 '14 at 20:59
  • @Fildor when I use that write method it says ByteBuffer cannot be converted to ByteBuffer[]? – user3339242 Nov 17 '14 at 21:00
  • @jtahlborn The FileChannel has a text file attached to it before reading into the bytebuffer – user3339242 Nov 17 '14 at 21:00
  • the FileChannel that you are reading from? The file on disk has extra bytes in it? – jtahlborn Nov 17 '14 at 21:02
  • Forget my comment jtahlborn is right. – Fildor Nov 17 '14 at 21:04
  • @jtahlborn When I read in the last few bytes remaining in the , it gives me 372 but it still sends it like there is 512 bytes by appending the last few bytes. – user3339242 Nov 17 '14 at 21:07
  • Do you do anything else with that buffer than shown in the question? – Fildor Nov 17 '14 at 21:07
  • @jtahlborn on the receiver side I am calling the bytebuffer.remaining() method to get the number of bytes I am receiving, on the sender side I am using bytebuffer.position() to get the amount I am sending – user3339242 Nov 17 '14 at 21:09
  • Are you calling position() _afer_ you call clear()? – jtahlborn Nov 17 '14 at 21:10
  • @jtahlborn I call position before I writer and after I flip. So before clear – user3339242 Nov 17 '14 at 21:11
  • call `remaining()` after you flip and before you write to determine how many bytes you will write. – jtahlborn Nov 17 '14 at 21:12
  • 1
    also, in future questions, don't omit the relevant code. – jtahlborn Nov 17 '14 at 21:14
  • @jtahlborn Changed it to remaining() and It still says sending out 374 bytes – user3339242 Nov 17 '14 at 21:16
  • 2
    isn't that what it is supposed to say...? – jtahlborn Nov 17 '14 at 21:16
  • Yes ok so heres the issue: in my textfile I have sentence 45 sentence 46 sentence 47 and last sentence. In the second to last packet it sends sentence 45, then in the last packet it sends sentence 46,47, the last sentence and the last 140 bytes it sends the last part of sentence 45 – user3339242 Nov 17 '14 at 21:17
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/65101/discussion-between-user3339242-and-jtahlborn). – user3339242 Nov 17 '14 at 21:19
  • 1
    i'm pretty sure in your previous comment, you indicated that the datagram consumer was receiving the correct data. if that's not the case, then the problem is probably in your consumer. if that is the case, then i fail to see why you say "i'm sending incorrect data but the consumer is receiving correct data"? – jtahlborn Nov 17 '14 at 21:20
  • @jtahlborn I explained it more in the chat – user3339242 Nov 17 '14 at 21:23
  • 1
    unfortunately, you are not explaining it in a meaningful way. i would suggest sitting down with a debugger and determining _exactly_ where the problem is, then see if you can fix it. if not, put _all_ the details into a new question, and then maybe someone will be able to help you. – jtahlborn Nov 17 '14 at 21:25

1 Answers1

3
  1. Using a DatagramChannel this way is really never going to work. You're just sending chunks of the file which may or may not arrive, or arrive twice, or more, in any order. Use TCP.

  2. Even if it does magically work, and I have my suspicions that there are further bugs in the 'omitted code', or the receiving code:

    while (fChannel.read(bBuffer) > 0) {
    
        bBuffer.flip();
        datagramChannel.write(bBuffer);
        bBuffer.clear();
    
        //omitted code
    }
    

    The correct version of the copy loop between channels in Java is as follows:

    while (fChannel.read(buffer) > 0 || buffer.position() > 0) {    
        buffer.flip();
        datagramChannel.write(bBuffer);
        buffer.compact();
    }
    

    Note that you must continue writing while there is still anything in the buffer (buffer.position() > 0), and that you must compact() rather than clear() so as not to assume that the write() emptied the buffer.

  3. If it wasn't a DatagramChannel you should use a buffer much larger than 512, for example 8192.

user207421
  • 305,947
  • 44
  • 307
  • 483