BlackBerry Forums Support Community               

Closed Thread
 
LinkBack Thread Tools
Old 02-27-2007, 09:32 AM   #1 (permalink)
Knows Where the Search Button Is
 
Join Date: Nov 2006
Model: 8310
Carrier: AT&T (formerly Cingular)
Posts: 47
Post Thanks: 0
Thanked 0 Times in 0 Posts
Default Max IO Connections on device but not simulator?

Please Login to Remove!

My application downloads a jpeg from a server and then displays the image on the screen. While running on the simulator it will run in a continuous loop, downloading new images and displaying them on the screen. After the data for each image is received my SocketConnection and InputStreamReader are both closed using the close() command. The application will run merrily along forever on the simulator, but when I load it on the device (7130c) after about 5-6 images are loaded I get the dreaded Max IO Connections exception. I tried making the thread sleep for 4 seconds after closing the connections but that doesn't seem to work.

I can't understand why this exception would be thrown on the actual device and not the simulator. I'm on a BES but using the deviceside=true flag in my connection string.

Anyone have any ideas?
Offline  
Old 02-27-2007, 09:47 AM   #2 (permalink)
Thumbs Must Hurt
 
Join Date: Jan 2007
Model: 8800
Carrier: Orange
Posts: 181
Post Thanks: 0
Thanked 0 Times in 0 Posts
Default

I had this EXACT problem. I solved it in the end by only ever using one connection object throughout the whole application!
Offline  
Old 02-27-2007, 10:00 AM   #3 (permalink)
Knows Where the Search Button Is
 
Join Date: Nov 2006
Model: 8310
Carrier: AT&T (formerly Cingular)
Posts: 47
Post Thanks: 0
Thanked 0 Times in 0 Posts
Default

Quote:
Originally Posted by bdowling
I had this EXACT problem. I solved it in the end by only ever using one connection object throughout the whole application!
Hmm, I wasn't hoping to hear that.

So, how did you go about using the one connection object throughout? Did you have it connect in a separate thread and then after the thread exited just have the new thread use the same connection over? Or, did you have the thread loop continuously waiting for a command?

I'm curious to know how you did it. I'm new when it comes to sockets and java programming so I'm still learning. Sockets are much easier to work with in VB
Offline  
Old 02-27-2007, 10:36 AM   #4 (permalink)
Thumbs Must Hurt
 
Join Date: Jan 2007
Model: 8800
Carrier: Orange
Posts: 181
Post Thanks: 0
Thanked 0 Times in 0 Posts
Default

I created a class called ConnectionManager that is basically a wrapper around a connection object. Anytime anything wants to make a connection they get the object from the ConnectionManager. If the connection ever times out you can just call ConnectionManager.reset() to reset the object.

Code:
public class ConnectionManager
{
    private static SocketConnection connection = null;
    private static DataOutputStream output = null;
    private static DataInputStream input = null;

    private String url;


    public ConnectionManager (String url)
    {
        this.url = url;
    }


    public SocketConnection getConnection ()
    {
        if (connection == null)
        {
            try
            {
                // setup our connection to the DNS
                connection = (SocketConnection) Connector.open( url, Connector.READ_WRITE, true );
                // disable keep alive
                connection.setSocketOption( SocketConnection.KEEPALIVE, 0 );
                // disable linger
                connection.setSocketOption( SocketConnection.LINGER, 0 );
            }
            catch (final IOException e)
            {
                this.reset();
                return getConnection();
            }
        }
        return connection;

    }


    public DataOutputStream getDataOutputStream ()
    {
        if (output == null)
        {
            try
            {
                output = getConnection().openDataOutputStream();
            }
            catch (final IOException e)
            {
                this.reset();
                return getDataOutputStream();
            }
        }
        return output;
    }


    public DataInputStream getDataInputStream ()
    {
        if (input == null)
        {
            try
            {
                input = getConnection().openDataInputStream();
            }
            catch (final IOException e)
            {
                this.reset();
                return getDataInputStream();
            }
        }
        return input;
    }


    public void reset ()
    {
        try
        {
            input.close();
        }
        catch (IOException e)
        {
            // no concern, we want to close it anyway
        }
        input = null;

        try
        {
            output.close();
        }
        catch (IOException e)
        {
            // no concern, we want to close it anyway
        }
        output = null;

        try
        {
            connection.close();
        }
        catch (IOException e)
        {
            // no concern, we want to close it anyway
        }
        connection = null;
    }

}
You have to make sure you don't access the connection from multiple threads at the same time though!

Hope that helps
Offline  
Old 02-27-2007, 11:37 AM   #5 (permalink)
Knows Where the Search Button Is
 
Join Date: Nov 2006
Model: 8310
Carrier: AT&T (formerly Cingular)
Posts: 47
Post Thanks: 0
Thanked 0 Times in 0 Posts
Default

Quote:
Originally Posted by bdowling
I created a class called ConnectionManager that is basically a wrapper around a connection object. Anytime anything wants to make a connection they get the object from the ConnectionManager. If the connection ever times out you can just call ConnectionManager.reset() to reset the object.

Code:
public class ConnectionManager
{
    private static SocketConnection connection = null;
    private static DataOutputStream output = null;
    private static DataInputStream input = null;

    private String url;


    public ConnectionManager (String url)
    {
        this.url = url;
    }


    public SocketConnection getConnection ()
    {
        if (connection == null)
        {
            try
            {
                // setup our connection to the DNS
                connection = (SocketConnection) Connector.open( url, Connector.READ_WRITE, true );
                // disable keep alive
                connection.setSocketOption( SocketConnection.KEEPALIVE, 0 );
                // disable linger
                connection.setSocketOption( SocketConnection.LINGER, 0 );
            }
            catch (final IOException e)
            {
                this.reset();
                return getConnection();
            }
        }
        return connection;

    }


    public DataOutputStream getDataOutputStream ()
    {
        if (output == null)
        {
            try
            {
                output = getConnection().openDataOutputStream();
            }
            catch (final IOException e)
            {
                this.reset();
                return getDataOutputStream();
            }
        }
        return output;
    }


    public DataInputStream getDataInputStream ()
    {
        if (input == null)
        {
            try
            {
                input = getConnection().openDataInputStream();
            }
            catch (final IOException e)
            {
                this.reset();
                return getDataInputStream();
            }
        }
        return input;
    }


    public void reset ()
    {
        try
        {
            input.close();
        }
        catch (IOException e)
        {
            // no concern, we want to close it anyway
        }
        input = null;

        try
        {
            output.close();
        }
        catch (IOException e)
        {
            // no concern, we want to close it anyway
        }
        output = null;

        try
        {
            connection.close();
        }
        catch (IOException e)
        {
            // no concern, we want to close it anyway
        }
        connection = null;
    }

}
You have to make sure you don't access the connection from multiple threads at the same time though!

Hope that helps

Thanks for posting that wrapper. I only have one thread that does any sending or receiving. So I'll keep my fingers crossed.
Offline  
Old 02-28-2007, 10:49 AM   #6 (permalink)
Knows Where the Search Button Is
 
Join Date: Feb 2007
Model: 9000
Carrier: SFR
Posts: 48
Post Thanks: 0
Thanked 0 Times in 0 Posts
Default

BB devices have a (very) small number of connexions allowed.
If connections are not closed properly (stream first then socket) these connexion stay alive ...
By the way, it look like there is a delay on the efficient close of a connection. (That 's why you 're already using the sleep).

If you re closing properly your socket perhaps you just want to replay the connection when getting a "max connection open" Or perhaps you just want to keep your connection open ...
Offline  
Old 02-28-2007, 12:03 PM   #7 (permalink)
CrackBerry Addict
 
Join Date: Jun 2005
Location: Manchester, UK
Model: BOLD
Carrier: t-mobile
Posts: 714
Post Thanks: 0
Thanked 0 Times in 0 Posts
Default

it's good practice to always use 'finally'' in your connection class, that way no matter where an error gets thrown you always have the chance to close the connection elegantly:

try{
//code
}catch(someexception e){
//exception handler
}finally{
//close the connection
}
__________________
new job doesn't allow a public profile - please do not contact this user with questions, you will not get a response. good luck!
Offline  
Old 02-28-2007, 08:26 PM   #8 (permalink)
Knows Where the Search Button Is
 
Join Date: Nov 2006
Model: 8310
Carrier: AT&T (formerly Cingular)
Posts: 47
Post Thanks: 0
Thanked 0 Times in 0 Posts
Default

I wound up using bdowling's class and building upon it to check for network coverage and the radio being enabled. In my app I decided to create two ConnectionManager classes (one for writing to the stream and one for reading from it) so that I wouldn't have to worry about the two threads accessing the class at the same time. My first app had only one socket thread but I decided two would be even better. Having two threads instead of one uses up a second socket connection but makes my life easier. So far, it seems to work great.

I just wish I knew why my original arrangement worked perfect on the simulator but blew up on the device.
Offline  
Old 03-22-2007, 09:02 AM   #9 (permalink)
Knows Where the Search Button Is
 
Join Date: Nov 2006
Model: 8310
Carrier: AT&T (formerly Cingular)
Posts: 47
Post Thanks: 0
Thanked 0 Times in 0 Posts
Default

Well, I'm reviving this thread because I found that removing the deviceside=true flag from my connector string seems to have resolved the problem I was having of non-closing threads. My server application now logs that the socket closed, previously the socket was held open. I'm on Cingular w/a BES but I believe the deviceside=true bypasses the BES? I thought it was possible now to do sockets over WAP with the newer OS's? Is there a config I need to make on my blackberry or maybe a setting? I'll do some searching and see if I can turn anything up.
Offline  
Closed Thread


Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On





Copyright 2004-2014 BlackBerryForums.com.
The names RIM and BlackBerry are registered Trademarks of BlackBerry Inc.