[Android] Remote access find a free port to avoid "address already in use" exception

Nicolas Pomepuy git at videolan.org
Thu Dec 7 07:28:08 UTC 2023


vlc-android | branch: refs/tags/3.6.0 | Nicolas Pomepuy <nicolas at videolabs.io> | Thu Dec  7 08:26:51 2023 +0100| [326d22210cfb4095bafa173b1e8e0abaddeea482] | committer: Nicolas Pomepuy

Remote access find a free port to avoid "address already in use" exception

> https://code.videolan.org/videolan/vlc-android/commit/326d22210cfb4095bafa173b1e8e0abaddeea482
---

 .../videolan/vlc/webserver/RemoteAccessServer.kt   | 26 ++++++++++++++++++++--
 1 file changed, 24 insertions(+), 2 deletions(-)

diff --git a/application/webserver/src/main/java/org/videolan/vlc/webserver/RemoteAccessServer.kt b/application/webserver/src/main/java/org/videolan/vlc/webserver/RemoteAccessServer.kt
index f043e203e6..b86cdbfaf5 100644
--- a/application/webserver/src/main/java/org/videolan/vlc/webserver/RemoteAccessServer.kt
+++ b/application/webserver/src/main/java/org/videolan/vlc/webserver/RemoteAccessServer.kt
@@ -111,6 +111,7 @@ import java.io.File
 import java.math.BigInteger
 import java.net.InetAddress
 import java.net.NetworkInterface
+import java.net.ServerSocket
 import java.security.KeyPairGenerator
 import java.security.KeyStore
 import java.security.PrivateKey
@@ -341,6 +342,27 @@ class RemoteAccessServer(private val context: Context) : PlaybackService.Callbac
         return retrieveKeystorePassword(attempts + 1)
     }
 
+    /**
+     * Finds a free port to use
+     *
+     * @param default the default port to test
+     * @return a port number
+     */
+    private fun getFreePort(default:Int): Int {
+        if (BuildConfig.DEBUG) Log.d(this::class.java.simpleName, "Testing port: $default")
+        var socket: ServerSocket? = null
+        val port = try {
+            socket = ServerSocket(default)
+            socket.localPort
+        } catch (e: Exception) {
+            if (default == 0) throw IllegalStateException("Cannot find a free port to use")
+            return getFreePort(0)
+        } finally {
+            socket?.close()
+        }
+        return port
+    }
+
     /**
      * Generate the server
      *
@@ -386,7 +408,7 @@ class RemoteAccessServer(private val context: Context) : PlaybackService.Callbac
         val environment = applicationEngineEnvironment {
             log = LoggerFactory.getLogger("ktor.application")
             connector {
-                port = 8080
+                port = getFreePort(8080)
             }
             sslConnector(
                     store,
@@ -394,7 +416,7 @@ class RemoteAccessServer(private val context: Context) : PlaybackService.Callbac
                     { password },
                     { password }
             ) {
-                this.port = 8443
+                this.port = getFreePort(8443)
             }
             module {
 



More information about the Android mailing list