Close serverSocket more reliably

This commit is contained in:
edr
2020-04-15 22:50:49 +02:00
parent 1848126888
commit a4c6d39265
2 changed files with 37 additions and 47 deletions

View File

@@ -11,8 +11,8 @@ android {
defaultConfig { defaultConfig {
applicationId "protect.babymonitor" applicationId "protect.babymonitor"
minSdkVersion 16 minSdkVersion 19
targetSdkVersion 17 targetSdkVersion 26
versionCode 3 versionCode 3
versionName "0.3" versionName "0.3"
} }

View File

@@ -20,6 +20,9 @@ import java.io.IOException;
import java.io.OutputStream; import java.io.OutputStream;
import java.net.ServerSocket; import java.net.ServerSocket;
import java.net.Socket; import java.net.Socket;
import java.util.Objects;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import android.app.Activity; import android.app.Activity;
import android.content.Context; import android.content.Context;
@@ -45,7 +48,13 @@ public class MonitorActivity extends Activity
NsdManager.RegistrationListener _registrationListener; NsdManager.RegistrationListener _registrationListener;
Thread _serviceThread; ServerSocket currentSocket = null;
Executor singleThreadExecutor = Executors.newSingleThreadExecutor();
Object connectionToken = null;
int currentPort = 10000;
private void serviceConnection(Socket socket) throws IOException private void serviceConnection(Socket socket) throws IOException
{ {
@@ -101,21 +110,18 @@ public class MonitorActivity extends Activity
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
setContentView(R.layout.activity_monitor); setContentView(R.layout.activity_monitor);
final Object currentToken = new Object();
connectionToken = currentToken;
_serviceThread = new Thread(new Runnable() singleThreadExecutor.execute(new Runnable() {
{
@Override @Override
public void run() public void run()
{ {
while(Thread.currentThread().isInterrupted() == false) while(Objects.equals(connectionToken, currentToken))
{ {
ServerSocket serverSocket = null; try (ServerSocket serverSocket = new ServerSocket(currentPort))
try
{ {
// Initialize a server socket on the next available port. currentSocket = serverSocket;
serverSocket = new ServerSocket(10000);
// Store the chosen port. // Store the chosen port.
final int localPort = serverSocket.getLocalPort(); final int localPort = serverSocket.getLocalPort();
@@ -124,48 +130,28 @@ public class MonitorActivity extends Activity
registerService(localPort); registerService(localPort);
// Wait for a parent to find us and connect // Wait for a parent to find us and connect
try {
Socket socket = serverSocket.accept(); Socket socket = serverSocket.accept();
Log.i(TAG, "Connection from parent device received"); Log.i(TAG, "Connection from parent device received");
// We now have a client connection. // We now have a client connection.
// Unregister so no other clients will // Unregister so no other clients will
// attempt to connect // attempt to connect
serverSocket.close();
serverSocket = null;
unregisterService(); unregisterService();
try
{
serviceConnection(socket); serviceConnection(socket);
} } catch (IOException e) {
finally
{
socket.close();
}
}
catch(IOException e)
{
Log.e(TAG, "Connection failed", e); Log.e(TAG, "Connection failed", e);
} }
// If an exception was thrown before the connection
// could be closed, clean it up
if(serverSocket != null)
{
try
{
serverSocket.close();
} }
catch(IOException e) catch(IOException e)
{ {
Log.e(TAG, "Failed to close stray connection", e); // Just in case
} currentPort++;
serverSocket = null; Log.e(TAG, "Failed to open server socket. Port increased to " + currentPort, e);
} }
} }
} }
}); });
_serviceThread.start();
final TextView addressText = (TextView) findViewById(R.id.address); final TextView addressText = (TextView) findViewById(R.id.address);
@@ -194,10 +180,14 @@ public class MonitorActivity extends Activity
unregisterService(); unregisterService();
if(_serviceThread != null) connectionToken = null;
if(currentSocket != null)
{ {
_serviceThread.interrupt(); try {
_serviceThread = null; currentSocket.close();
} catch (IOException e) {
Log.e(TAG, "Failed to close active socket on port "+currentPort);
}
} }
super.onDestroy(); super.onDestroy();