I have a child activity that creates an asynchronous task that opens a Java ServerSocket and calls accept() on that serverPort.
Now, in this Activity's onStop() method, I have a call to cancel() my asynchronous task. In my asynchronous class, in both the onPostExecute() and onCancelled() methods, I close the serverSocket (as well as any other dataStreams or Sockets that may have been opened).
All my code runs properly. Through debugging, I know for a fact that if I:
- Run the application linearly up to the point where the serverSocket starts to accept() connections.
- Hit the back button, closing the child activity and calling its onStop() method which then cancels the asynchronous task in question and calls close() on the serverSocket.
- Run the child activity again, creating the new Asynchronous thread, and the code runs up to the point where I create a serverSocket on the same port as the first one. However, it throws an IO exception and says that the port is already in use.
No matter how long I wait restarting this child Activity will just shoot off IO exceptions claiming that the port is already taken. However, doing things like:
Restarting the device
Reinstalling the Application
Completely Closing the Application (instead of just relaunching the child activity from its parent activity)
Seem to free up the port.
How exactly does Android refresh/free up ports that you've used? Is there any way I could call a refresh on those ports programatically?
And before the obvious questions arise, I'm using P2P and java sockets, so yes, I do actually want to use direct connection to sockets and direct accept on static local ports and the such.
EDIT: formatting
EDIT2: After changing
serverSocket = new ServerSocket(portNumber);
socket = serverSocket.accept();
To:
serverSocket = new ServerSocket();
serverSocket.setReuseAddress(true);
serverSocket.bind(new InetSocketAddress("192.168.49.1", 8000));
socket = serverSocket.accept();
I am now getting a java.net.BindException: bind failed: EADDNOTAVAIL (Cannot assign requested address) exception instead. (This only occurs after the first set of conditions. The first runthrough of the application still runs properly as it did before).
EDIT 3: If I ever find a way to properly do this, I'll post it in an edit, but for now (debugging) I'm just going to go the quick and dirty route and completely kill the app whenever the user presses the back button and restart the application to the main activity. This seems to clear up the port bind.