I'm experiencing the same problem. I've opened an HTTP socket to a web server, and then opened the input stream and output stream from the socket. Using the sockets from my app works fine both in the simulator and in a real device (tested on 8707v and 8100), and closing the socket works fine on the simulator.
However, when using the app in a real device, over BES, something goes wrong when the app attempts to close the sockets. It seems that the final handshake of the three-handshake TCP socket-closing procedure is not sent from the device to the web server, perhaps being somehow eaten by BES. This leaves the socket hanging in the server, which keeps it open until the app closes (because this is the way we've programmed the web server to work).
As our app closes an old socket and opens a new one as the user moves from screen to screen, the problem leads, in the worst case, to the app having lots of open sockets, using up the resources, and possibly freezing the app.
We've added the code suggested in this thread to closing the socket: we're closing both the input and output streams before closing the socket; we're sleeping for a bit after each call of close; and we're enclosing the closes inside a try-block. Even lengthening the sleep time to one second did not affect the problem.
Below, the code that opens the sockets and the code that closes them. Note that at the end of the method CloseSocket, the closes never throw an exception, and at the end, the code always reports that three closes were successful. However, the sockets still hang there.
Any ideas, anybody???
Code:
/**
* Send the initial request.
*/
public synchronized void SendRequest() throws IOException, OwnException
{
// returns
// "socket://<ip_address>:<port>;deviceside=true;apn=internet"
// where <ip_address> is the configured IP address and <port>
// is the configured port:
String service = monitor_.GetConnectionService();
SocketConnection socket = ( SocketConnection )Connector.open( service );
socket.setSocketOption( SocketConnection.DELAY, 0 );
if ( socket != null )
{
socket_in_ = socket.openDataInputStream();
socket_out_ = socket.openDataOutputStream();
if ( socket_ == null )
{
socket_ = socket;
}
else
{
throw new OwnException( "unclosed socket!" );
}
SendRequest( message_, socket_out_ );
}
else
{
// No socket is available, most likely mobile data is
// down. Error ourselves.
ChangeState( state_.ErrorOrOtherFinalEvent( this ) );
}
}
/**
* @param socket SocketConnection to close.
* @param socket_in DataInputStream to close.
* @param socket_out DataOutputStream to close.
*/
private static void CloseSocket( SocketConnection socket,
DataInputStream socket_in,
DataOutputStream socket_out )
{
int connections_closed = 0;
try
{
if ( socket_in != null )
{
// log this
++ connections_closed;
socket_in.close();
Thread.sleep( GlobalConstants.SLEEP_AFTER_CLOSING_SOCKET );
}
}
catch ( IOException ex )
{
-- connections_closed;
// log this
}
catch ( InterruptedException ex )
{
-- connections_closed;
// log this
}
finally
{
socket_in = null;
}
try
{
if ( socket_out != null )
{
// log this
++ connections_closed;
socket_out.close();
Thread.sleep( GlobalConstants.SLEEP_AFTER_CLOSING_SOCKET );
}
}
catch ( IOException ex )
{
-- connections_closed;
// log this
}
catch ( InterruptedException ex )
{
-- connections_closed;
// log this
}
finally
{
socket_out = null;
}
try
{
if ( socket != null )
{
// log this
++ connections_closed;
socket.close();
Thread.sleep( GlobalConstants.SLEEP_AFTER_CLOSING_SOCKET );
}
}
catch ( IOException ex )
{
-- connections_closed;
// log this
}
catch ( InterruptedException ex )
{
-- connections_closed;
// log this
}
finally
{
socket = null;
}
// log connections_closed
}