views:

69

answers:

2

My application loops through about 200 urls that are all jpg images. In the simulator it reads ok, then stores the byte array in persistentStore with no problems. On the device, it gives java.io.IOException: TCP read timed out on basically every image. Every now and then, one gets through. Not even sure how. The image sizes don't give insight either. Some are 6k, some are 11k. Size doesn't seem to matter for timing out.

I'll try to post what I believe to be the relevant code, but I am not really an expert here, so if I left something out, please say so.

Call http connection through loop and join thread:

for(int i = 0; i < images.size(); i ++)
  {
      try {
       String url = images.elementAt(i).toString();
                HttpRequest data3 = new HttpRequest(url, "GET", false);
          data3.start();

    data3.join();

   } catch (IOException e) {
    Dialog.inform("wtf " + e);
   }
  }

Make the actual connection in HttpConnection class with the proper suffix:

try
  { 
   HttpConnection connection = (HttpConnection)Connector.open(url + updateConnectionSuffix());


   int responseCode = connection.getResponseCode();
   if(responseCode != HttpConnection.HTTP_OK)
   {
    connection.close();
    return;
   }

   String contentType = connection.getHeaderField("Content-type");
   long length = connection.getLength();

   InputStream responseData = connection.openInputStream();
   connection.close();

   outputFinal(responseData, contentType, length);
  }
  catch(IOException ex)
  {

  } catch (SAXException ex) {

  } catch (ParserConfigurationException ex) {

  }

Finally, read the stream and write the bytes to a byte array:

else if(contentType.equals("image/png") || contentType.equals("image/jpeg") || contentType.equals("image/gif"))
  {
   try
            {
    if((int) length < 1)
     length = 15000;

             byte[] responseData = new byte[(int) length];
                int offset = 0;
                int numRead = 0;
                StringBuffer rawResponse = new StringBuffer();

                int chunk = responseData.length-offset;
                if(chunk < 1)
                 chunk = 1024;

                while (offset < length && (numRead=result.read(responseData, offset, chunk)) >= 0){
                 rawResponse.append(new String(responseData, offset, numRead));
                 offset += numRead;
                }

                String resultString = rawResponse.toString();
                byte[] dataArray = resultString.getBytes(); 

                result.close();

                database db = new database();
                db.storeImage(venue_id, dataArray);
            }
            catch( Exception e )
            {
             System.out.println(">>>>>>>----------------> total image fail: " + e);   
            }


  }

Things to consider:
Length is always byte length in simulator. In device it is always -1.
The chunk var is a test to see if I force a 15k byte array, will it try to read as expected since byte[-1] gave an out of bounds exception. The results are the same. Sometimes it writes. Mostly it times out.

Any help is appreciated.

+2  A: 

You can adjust the length of TCP timeouts on Blackberry using the parameter 'ConnectionTimeout'.

In your code here:

HttpConnection connection = (HttpConnection)Connector.open(url + updateConnectionSuffix());

You'll want to append ConnectionTimeout. You might write it into updateConnectionSuffix() or just append it.

    HttpConnection connection = (HttpConnection)Connector.open(url + updateConnectionSuffix() + ";ConnectionTimeout=54321");

This sets the timeout to 54321 milliseconds.

Timeouts occur when the client is waiting for the server to send an ack and it doesn't get one in a specified amount of time.

edit: also, are you able to use the browser and stuff? You may also want to play with the deviceside parameter.

Tom Dignan
+2  A: 

I think the problem may be that you're closing the connection before reading the bytes from the input stream. Try moving the connection.close() after the bytes have been read in.

Marc Novakowski
Thank you! I applied both solutions and the app is downloading and storing images as expected now. If I have time to further debug, I can pinpoint exactly which solved this and credit the one that best answers the problem so future programmers can benefit accurately from this.
Kai
+1 for finding that, that was a lot of code that i didn't read ;D
Tom Dignan