Results 1 to 11 of 11
  1. #1
    Master Zero is offline Member
    Join Date
    May 2008
    Posts
    26
    Rep Power
    0

    Default BufferUnderflowException

    I am trying to transfer a large image from a VB.NET server to a Java Applet client but I keep getting this annoying error and I canít figure out why. Can anyone help me? I tried bugging both at the same time to watch the transfer happen, and I notice that at certain points, the buffers arenít exactly the same. For one thing, I keep seeing negative numbers in one buffer why the other has positives. In the java code, I try read the byte array that is being sent from the server. Maybe someone knows of a better way to read an image from a stream?

    Java Code:
    	public class Read extends Thread {
    		public void run() {
    			int size = 0;
    			// Check if we are connected
    			if (client != null && reader != null) {
    				try {
    					// Variables
    					int total = 0;
    					String line = "";
    					
    					ftpReader.read(buffer.array(), 0, buffer.capacity()); // Read into buffer
    					
    					for (int i = 0; i < buffer.capacity(); i++) {
    						line += (char)buffer.get(i); // Loop to get all the characters
    					}
    					//JOptionPane.showMessageDialog(null, line);
    					//size = Integer.parseInt(line); // We just got the size of the image
    					byte[] data = new byte[4096054]; // Create a buffer with that size
    					
    					// Send the signal
    					writer.write("SendFile".getBytes(), 0, "SendFile".length());
    					
    					while (4096054 != total) {
    						bytesRead = ftpReader.read(buffer.array(), 0, buffer.capacity());
    						buffer.get(data, 0, bytesRead);
    						total += bytesRead;
    					}
    					
    					ByteArrayInputStream imageStream = new ByteArrayInputStream(data);
    					Image image = ImageIO.read(imageStream);
    				} catch (IOException e) {
    					e.printStackTrace();
    				}
    			}
    			
    			run(); // Calls the thread again
    		}
    	}

  2. #2
    Nicholas Jordan's Avatar
    Nicholas Jordan is offline Senior Member
    Join Date
    Jun 2008
    Location
    Southwest
    Posts
    1,018
    Rep Power
    7

    Post Advanced Image API?

    Quote Originally Posted by Master Zero View Post
    ...annoying error and I canít figure out why....
    Java Code:
    run(); // Calls the thread again
    would seem to over/underflow
    Quote Originally Posted by Master Zero View Post
    Maybe someone knows of a better way to read an image from a stream?
    What have you looked at in the Advanced Image API?
    Introduction to Programming Using Java.
    Cybercartography: A new theoretical construct proposed by D.R. Fraser Taylor

  3. #3
    Master Zero is offline Member
    Join Date
    May 2008
    Posts
    26
    Rep Power
    0

    Default

    Actually, the error occurs in the while loop (the second pass always) at this line;

    Java Code:
    buffer.get(data, 0, bytesRead);
    I don’t really know much about java, so I have been arbitrarily searching Yahoo and Google for methods on loading images form bytes, but I have only found the opposite thus far. I’ve stitched bits of code to try and get this to work, but I can’t even get pass the transferring phase. The image is real large, exactly 4096054 bytes in size. So I only send 8193 bytes at a time. But it’s on the second pass - second group of 8193 bytes - I get the error, when I know for a fact that data was sent.

  4. #4
    Master Zero is offline Member
    Join Date
    May 2008
    Posts
    26
    Rep Power
    0

    Default

    I fix it by replacing
    Java Code:
    byte[] data = new byte[4096054];
    with
    Java Code:
    ByteArrayOutputStream data = new ByteArrayOutputStream();
    so now the new code looks like this:

    Java Code:
    	public class Read extends Thread {
    		public void run() {
    			int size = 0;
    			// Check if we are connected
    			if (client != null && ftpClient != null) {
    				try {
    					// Variables
    					int total = 0;
    					String line = "";
    					
    					ftpReader.read(buffer, 0, buffer.length); // Read into buffer
    					
    					for (int i = 0; i < buffer.length; i++) {
    						if (buffer[i] == 0) break;
    						line += (char)buffer[i]; // Loop to get all the characters
    					}
    					
    					size = Integer.parseInt(line); // We just got the size of the image
    					ByteArrayOutputStream data = new ByteArrayOutputStream(); // Create a buffer with that size
    					
    					// Send the signal
    					writer.write("SendFile".getBytes(), 0, "SendFile".length());
    					
    					while (total < size) {
    						bytesRead = ftpReader.read(buffer, 0, buffer.length);
    						data.write(buffer, 0, bytesRead);
    						total += bytesRead;
    					}
    					
    					//byte[] img = data.toByteArray();
    					ByteArrayInputStream imageStream = new ByteArrayInputStream(data.toByteArray());
    					image = ImageIO.read(imageStream);
    					Graphics g = text.getGraphics();
    					g.drawImage(image, 0, 0, text);
    				} catch (IOException e) {
    					e.printStackTrace();
    				}
    			}
    			
    			run(); // Calls the thread again
    		}
    	}

  5. #5
    Nicholas Jordan's Avatar
    Nicholas Jordan is offline Senior Member
    Join Date
    Jun 2008
    Location
    Southwest
    Posts
    1,018
    Rep Power
    7

    Post

    Couple of short questions to avoid wasted effort.

    First, the call to run() inside run is recursive, not necessarily wrong - but does not seem to me to be the way to do a |-->|-->| operation would not seem to be recursive to me. Second, most Streams operate one byte at a time, I intuitively set up a buffer ~ 8192 and 4096 are handy sizes though the ram will operate far faster than most network and disc activity so I try to take some portion of L-2 as a first guess.

    Then, I do not at this point see where buffer is defined ( allocated and it's type ) so to start with let's see about building a FIFO of some kind. That is readily available as LinkedList but I do it as a RoundRobin because I feel more comfortable with that construct. Then, to note, I tried to read the AdvancedImaging API but did not get past the intro so maybe we both learn something.
    Introduction to Programming Using Java.
    Cybercartography: A new theoretical construct proposed by D.R. Fraser Taylor

  6. #6
    Norm's Avatar
    Norm is offline Moderator
    Join Date
    Jun 2008
    Location
    Eastern Florida
    Posts
    16,589
    Rep Power
    23

    Default

    Can you post the full text of the error message?
    What is ftpReader? and the read method? And buffer?

  7. #7
    Master Zero is offline Member
    Join Date
    May 2008
    Posts
    26
    Rep Power
    0

    Default

    There is a method to my madness...

    I have the receiving code in its own thread because it will constantly receive an image byte array, preceded by header information. The reason I have it looping inside the thread is because the total file size is greater than the buffer size.

    Java Code:
    1. Server --> accept client
    2. Server --> send header info (file size)
    3. Server <-- client sends (ready signal)
    4. Server --> sends image to client
    5. Client loops until all bytes are collected
    6. Client loads image
    7. Start again at step 2
    So that is the basic flow of my client/server network, and why I have it in itís in thread, thus explains the run() Ė recursive call back to step 2.
    Buffer was of type ByteBuffer, which when the .get() method was call always threw the exception on the 2nd time it was called.

    public abstract byte get()
    Relative get method. Reads the byte at this buffer's current position, and then increments the position.
    Returns:
    The byte at the buffer's current position
    Throws:
    BufferUnderflowException - If the buffer's current position is not smaller than its limit
    I change buffer to type of byte[] which of course did not throw that exception anymore. Next I stored the collected bytes into a ByteArrayOutputStream data type which I later convert into a ByteArrayInputStream data type, which then allows me to convert it back into an image with ImageIO.

    The other variables were declared at global level - above the parent class - because of variable scope.

    I have several important objects declared above; two TCP socket objects (client & ftpClient), two PrintStream objects (writer & ftpWriter), and two BufferedInputStream objects (reader & ftpReader), amongst other things. Everything gets instantiated in init();

  8. #8
    Norm's Avatar
    Norm is offline Moderator
    Join Date
    Jun 2008
    Location
    Eastern Florida
    Posts
    16,589
    Rep Power
    23

    Default

    Can you post the full text of the error message?
    What is ftpReader? and the read method? And buffer?
    I asked the above because it can't be seen looking at your code. If all the doc were in the code, you could read it on one screen instead of having to scroll up and down to read the one and then the other.

    Why a recursive call instead of a loop?
    Last edited by Norm; 09-16-2008 at 03:28 AM.

  9. #9
    Master Zero is offline Member
    Join Date
    May 2008
    Posts
    26
    Rep Power
    0

    Default

    Actually, the error message was not in my code, I copied it from the API document. I still donít understand why the ByteBuffer would throw the exception, when it was allocated to have a huge amount of space, more than the received buffer.

    As for the recursive call:

    Well, both are implemented really. But the main reason is because I donít want the GUI to freeze as the socket waits to receive incoming data Ė block method. The other socket will be use to send information constantly as well, and the GUI will be updated as new images arrive.
    I loop within the recursive call because the first thing that is read when the run() is called is the header information. I canít have the client listen for header information when image data is flowing in, thus why I loop first, than recursively call the entire thing again, and again.

  10. #10
    Norm's Avatar
    Norm is offline Moderator
    Join Date
    Jun 2008
    Location
    Eastern Florida
    Posts
    16,589
    Rep Power
    23

    Default

    For the third time:
    Can you post the full text of the error message?
    Also try debugging your code by putting a println() statement in the loop to show the number of bytes read each time.

    What happens with your recursive call if either socket is null?
    Last edited by Norm; 09-16-2008 at 06:50 PM.

  11. #11
    Nicholas Jordan's Avatar
    Nicholas Jordan is offline Senior Member
    Join Date
    Jun 2008
    Location
    Southwest
    Posts
    1,018
    Rep Power
    7

    Default

    5. Client loops until all bytes are collected
    Java Code:
    public void run(){do{socket.read();}while(boolean dataAvailable);
    Java Code:
    catch(BufferUnderflowException  bue){System.out.println(bue.getMessage());}
    We get into the typing issue for the exception trapping so probably better to do catch ( Throwable t) {t.printMessage();} Until we see where exceptions are occuring, there may be more than one and message may be alterted in exception chaining depending on who wrote what code and where it is in the call stack: Probably we should get stack tracing enabled before this does a hard-spin on trying to get diagnostics from the runtime.
    Introduction to Programming Using Java.
    Cybercartography: A new theoretical construct proposed by D.R. Fraser Taylor

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •