Search code examples
kotlinsocketskotlin-coroutinesport-scanning

How to use coroutines to scan local IP addresses using Kotlin


I have an app that scans local IP addresses to connect to open port 8102. I've been able to get the correct IP address, but it takes a long time because each poll has a timeout of 200 milliseconds. That's the lowest I've been able to get it with success.

I guess my question is is there a way to use coroutines to split up the work and get the address sooner? Right now it's taking about 3 seconds and the address I'm targeting is only 192.168.0.21.

Here's my code:

fun init() = GlobalScope.launch(Dispatchers.IO) {
            //Get local ip
            DatagramSocket().use { socket ->
                socket.connect(InetAddress.getByName("8.8.8.8"), 10002)
                ip = socket.getLocalAddress().getHostAddress().split(".") as MutableList<String>
            }
            //Go through local addresses to find receiver
            txtOutput.text = ip.toString()
            prefix = ip[0] + "." + ip[1] + "." + ip[2] + "."

            var i = 1
            do {
                try {
                    client = Socket()
                    client.connect(InetSocketAddress(prefix + i.toString(), 8102), 200)
                } catch (e: Exception) {
                    print(e.toString())
                    i++
                }
            } while (!(client.isConnected) or (i > 254))
            targetIP = prefix + i.toString()
            client = Socket()
            try{
            client.connect(InetSocketAddress(targetIP, 8102), 150)
                if(client.isConnected){
                client.keepAlive = true}}
            catch (e:IOException){
                cancel("Could not connect")
            }

Solution

  • It is theoretically possible but you have to test it

    fun init() = GlobalScope.launch(Dispatchers.IO) {
        //Get local ip
        DatagramSocket().use { socket ->
            socket.connect(InetAddress.getByName("8.8.8.8"), 10002)
            ip = socket.getLocalAddress().getHostAddress().split(".") as MutableList<String>
        }
        //Go through local addresses to find receiver
        txtOutput.text = ip.toString()
        prefix = ip[0] + "." + ip[1] + "." + ip[2] + "."
    
    //    var i = 1
    //    do {
    //        try {
    //            client = Socket()
    //            client.connect(InetSocketAddress(prefix + i.toString(), 8102), 200)
    //        } catch (e: Exception) {
    //            print(e.toString())
    //            i++
    //        }
    //    } while (!(client.isConnected) or (i > 254))
        
        ///#########
        val answer= Channel<Int>()
    
        for (i in 0..254){
            launch {
                try { 
                    client = Socket()
                    client.connect(InetSocketAddress(prefix + i.toString(), 8102), 200)
                    answer.send(i)
                }catch (e:Exception){ }
    
            }
        }
        val i=answer.receive()
        ///#########
    
        targetIP = prefix + i.toString()
        client = Socket()
        try {
            client.connect(InetSocketAddress(targetIP, 8102), 150)
            if (client.isConnected) {
                client.keepAlive = true
            }
        } catch (e: IOException) {
            cancel("Could not connect")
        }
    
    }