I was testing my app what would happen if I turned off the device's internet, and it was crashing. I already preemptively added a bunch of catch case on the "init" code of the socket helper, and they doesn't seems to be getting triggered. Here's what my code looks like:
fun start() {
GlobalScope.launch(Dispatchers.IO) {
try {
basicSocket = DatagramSocket(UDP_SERVER_PORT)
val udpPayload = "some string payload"
basicSendToUDP(udpPayload, getBroadcastAddr())
while (true) {
basicReceiveFromUDP()
}
} catch (e: SocketException) {
Log.e(TAG, "Socket Error:", e)
} catch (e: SecurityException) {
Log.e(TAG, "Sec Error:", e)
} catch (e: IOException) {
Log.e(TAG, "IO Error:", e)
} catch (e: Exception) {
Log.e(TAG, "Error:", e)
}
}
}
That start()
method gets called around the top of my MainActivity
's onCreate
.
I already tried some different approach that looks like this:
val t = Thread {
try {
basicSocket = DatagramSocket(UDP_SERVER_PORT)
val udpPayload = "some string payload"
basicSendToUDP(udpPayload, getBroadcastAddr())
while (true) {
basicReceiveFromUDP()
}
} catch (e: Exception) {
Log.e(TAG, "Error:", e)
}
}
t.start()
But I'm still getting the same error:
java.io.IOException: sendto failed: ENETUNREACH (Network is unreachable) at libcore.io.IoBridge.maybeThrowAfterSendto(IoBridge.java:721) at libcore.io.IoBridge.sendto(IoBridge.java:688) at java.net.PlainDatagramSocketImpl.send(PlainDatagramSocketImpl.java:126) at java.net.DatagramSocket.send(DatagramSocket.java:723) at com.bsu.atlantis.utils.helpers.SocketHelper.basicSendToUDP$lambda$3(SocketHelper.kt:74)
basicSendToUDP()
looks like this:
fun basicSendToUDP(payload: String, iAddr: InetAddress) {
Thread {
val sendPacket =
DatagramPacket(
payload.toByteArray(),
payload.length,
iAddr,
UDP_SERVER_PORT
)
basicSocket.send(sendPacket)
}.start()
}
All the code I posted works perfectly when I turn on the WiFi on my device
The problem is that the code throwing is run in a different thread Thread { .. }.start()
in basicSendTuUDP()
. You should catch the exception inside that thread like so:
fun basicSendToUDP(payload: String, iAddr: InetAddress) {
Thread {
try {
val sendPacket =
DatagramPacket(
payload.toByteArray(),
payload.length,
iAddr,
UDP_SERVER_PORT
)
basicSocket.send(sendPacket)
} catch (e: Exception) {
Log.e(TAG, "Error:", e)
}
}.start()
}