1

Trying to Bind (and Send) as in the docs but it fails:

[akka://udp-test/system/IO-UDP-FF/selectors/$a/0] Successfully bound to [/127.0.0.1:64387]
Sending msg: bla
[akka://udp-test/system/IO-UDP-FF/selectors/$a/0] Can't assign requested address
[akka://udp-test/system/IO-UDP-FF/selectors/$a/0] Closing DatagramChannel after being stopped

Fails as above if the target address is a public ip like 62.138.0.158 or in the local network like 192.168.2.3, both of which respond to ping.

Succeeds if the target address is 127.0.0.1 (localhost) on any port.

Succeeds after changing the local address to my current ip in the local network (e.g.: 192.168.2.2)

Fails differently for an invalid ip

[akka://default/system/IO-UDP-FF/selectors/$a/1] Name resolution failed for remote address [invalid-ip:6969]

Succeeds if I do exactly as Simple Send in the docs instead. I.e., with the Bind replaced by SimpleSender. But I also need to listen in the same port and I expected it to work as the doc for Bind (and Send) says:

Sending datagrams is achieved by using the Send message


To reproduce:

import java.net.InetSocketAddress

import akka.actor.{Actor, ActorRef, ActorSystem, Props}
import akka.io.{IO, Udp}
import akka.io.Udp.Send
import akka.util.ByteString

object Main extends App {

  val system = ActorSystem("udp-test")

  val destAddr = new InetSocketAddress("62.138.0.158", 6969)
  private val props = Props(classOf[Listener], destAddr)
  val udp: ActorRef = system.actorOf(props, "udp-actor")

  Thread.sleep(500) //give time for the actor to be created
  udp ! "bla"

}

class Listener(remote: InetSocketAddress) extends Actor {
  import context.system
  IO(Udp) ! Udp.Bind(self, new InetSocketAddress("localhost", 0))

  def receive = {
    case Udp.Bound(local) =>
      context.become(ready(sender()))
    case other =>
      println(s"Received something else: $other")
  }

  def ready(socket: ActorRef): Receive = {
    case msg: String =>
      println(s"Sending msg: $msg")
      socket ! Send(ByteString(msg), remote)
    case other =>
      println(s"Received something else: $other")
  }
}

I'm running on MacOS.

Victor Basso
  • 5,556
  • 5
  • 42
  • 60

1 Answers1

0

Solved after setting the local address to 0.0.0.0, meaning "listen on every available network interface".

I had two network interfaces, each with an IP address:

  • 127.0.0.1 on the loopback interface
  • a 192.168.x.x in the local network, talking to a router.

By binding specifically to 127.0.0.1 I wouldn't get packets coming from the outside, addressed to my 192.168.x.x IP. So listening to "all of them" makes sense.

My code works fine now but I still don't get why this error occurred when sending.

Victor Basso
  • 5,556
  • 5
  • 42
  • 60