0

I seem to be having a small problem with MulticastSocket on Android: writing an SSDP-related application. The socket works just fine when I set everything up the first time, but when I stop discovery, and try to restart things, I just get a SocketException: Socket Closed. I'm not closing the socket, I'm simply stopping the Kotlin Coroutine that is responsible for calling socket.receive() in a loop. Example:

fun listenForPackets(): Flow<DatagramPacket> {
    return flow {
        multicastSocket.use {
            val incomingBuffer = ByteArray(MULTICAST_DATAGRAM_SIZE)
            while (true) {
                val incomingPacket = DatagramPacket(incomingBuffer, incomingBuffer.size)
                it.receive(incomingPacket)
                emit(incomingPacket)
                incomingPacket.length = incomingBuffer.size
            }
        }
    }
}

The problem

So the problem is that when I try to call that function again, I get a SocketException: Socket Closed. The socket initialization code is run once, meaning that toggling discovery on/off will use the same socket multiple times; the following code is run once throughout the whole application:

multicastSocket = MulticastSocket(MULTICAST_PORT)
multicastSocket.reuseAddress = true
multicastSocket.joinGroup(multicastGroup)
multicastLock.acquire()

What I have tried

My first thought was that I was not cancelling the Kotlin Coroutine correctly. As a result, I switched to using typical Java Threads, to no avail. Starting the thread the first time works, but, restarting discovery yields the same problem. I have also tried to not leave the group, and keep the multicastLock acquired - same problem.

What works

What works is having the initialization code (where I assign the socket, join the group, and acquire lock) run every time I need to start a scan. At the end of the scan, I reset all of the variables (leave group, release lock, close socket). So my question becomes - is this the correct approach? Or am I simply doing something else wrong?

Just to re-iterate, I'm discovering packets just fine, the issue is with restarting the discovery. Thank you in advance for any help!

  • Are you aware that `multicastSocket.use{ ... }` will call `close()` on the socket after the lambda has run? – Adrian K Dec 22 '20 at 09:08
  • Oh damn, it looks like that's the one thing I didn't consider at all when debugging this. That would do it - thank you! Want to post an answer and I'll mark it as accepted? – ivanempire Dec 22 '20 at 17:21

0 Answers0